什么是整数文字类型? 以及他们如何存储?
我刚刚开始学习C,现在有一个问题让我烦恼了一段时间。 如果我写
int i = -1; unsigned int j = 2; unsigned int k = -2;
整数文字-1
和2
和-2
的类型是什么,它如何转换为存储在signed int
和unsigned int
?
有符号整数是什么意思,变量或整数字的属性呢? 像-2
是有符号整数, 2
是无符号整数?
首先, -1
不是整数常量。 它是一个由一元运算符组成的表达式-
运算符应用于常量1
。
在C99和C11中,十进制整数常量的类型是int
, long int
或long long int
中的第一个,其值适合。 类似地,八进制或hex文字具有int
, unsigned int
, long int
, unsigned long int
, long long int
或unsigned long long int
。 详情见N1570 6.4.4.1。
-1
和-2
是常量表达式 。 一元运算符的结果与操作数具有相同的类型(即使该结果导致溢出,在大多数实现中都是-INT_MIN
)。
int i = -1;
常量1
和表达式-1
都是int
类型。 该值存储在int
对象i
; 不需要转换。 (严格来说,它从int
转换为int
,但这并不重要。)
unsigned int j = 2;
2
是int
类型。 它从int
转换为unsigned int
。
unsigned int k = -2;
-2
是int
类型。 它从int
转换为unsigned int
。 这一次,因为-2
超出了unsigned int
的范围,所以转换是非平凡的; 结果是UINT_MAX - 1
。
一些术语:
常量是其他一些语言所谓的文字 。 它是表示常量值的单个标记。 示例是1
和0xff
。
常量表达式是在编译时需要计算的表达式。 常量是常量表达式; 所以是一个表达式,其操作数是常量或常量表达式。 例子是-1
和2+2
。
在C99和C11
如果要指定整数的类型,可以使用整数常量 :
你可以用十进制,八进制或六进制表示写整数:
int decimal = 42; // nothing special int octal = 052; // 0 in front of the number int hexa = 0x2a; // 0x int HEXA = 0X2A; // 0X
十进制表示:
默认情况下,-1,0,1等的类型是int
, long int
或long long int
。 编译器必须达到可以处理您的值的类型:
int a = 1; // 1 is a int long int b = 1125899906842624; // 1125899906842624 is a long int
这只适用于有signed
值,如果你想要unsigned
值,你需要添加u或U:
unsigned int a = 1u; unsigned long int b = 1125899906842624u;
如果你想要long int
或long long int
而不是int
,你可以使用l或L:
long int a = 1125899906842624l;
你可以把你和l结合起来:
unsigned long int a = 1125899906842624ul;
最后,如果你只想要long long int
,你可以使用ll或LL:
unsigned long long int a = 1125899906842624ll;
再次,你可以与你结合。
unsigned long long int a = 1125899906842624ull;
八进制和hex表示:
如果没有后缀,整数将与int
, long int
, long long int
, unsigned int
, unsigned long int
和unsigned long long int
匹配。
int a = 0xFFFF; long int b = -0xFFFFFFFFFFFFFF; unsigned long long int c = 0xFFFFFFFFFFFFFFFF;
你与十进制表示没有区别。 l或L和ll或LL添加无符号值类型。
这类似于字符串文字 。
什么是整数文字-1和2和-2的类型,以及它如何转换为存储在signed int和unsigned int中?
正如chux之前所说的那样,C解析器/编译器“理解”你的文字作为有符号整数 – 总是如此。 然后将它们转换为适合您指定的变量,可以是不同类型的变量。 这样做,一些位可能会丢失或者可能会改变它们的含义(例如,为无符号整数赋值)。 有些编译器可能会警告你“字面超出范围”,其他编译器可以默默接受(并截断)你的文字。
你的意思是Signed Integer,也就是变量或整数字面的属性,比如-2是有符号整数,2是无符号整数。
它是变量的属性。 实际上,它是一种“类型” – 写成“两个字”的标识符。
我会说这取决于编译器和机器的架构。 给定8 bits = 1 byte
,下表总结了32位和64位计算机上具有(signed) int
和unsigned int
所需大小的不同Integer类型:
+------+------+---------+-------+--------+-------------+-----------+ |Type |char |short int|int |long int|long long int|int pointer| +------+-------+--------+-------+--------+-------------+-----------+ |32-bit|8 bits|16 bits |32 bits|32 bits |64 bits |32 bits | +------+------+---------+-------+--------+-------------+-----------+ |64-bit|8 bits|16 bits |32 bits|64 bits |64 bits |64 bits | +------+------+---------+-------+--------+-------------+-----------+
您可能知道,(signed) int
和unsigned int
之间的最大区别在于,在(signed) int
,最高有效位(MSB)是为整数的符号保留的,因此:
- 具有n位的(带符号)
int
可以具有-(2^(n-1))
到(2^(n-1))-1
- 具有n位的
unsigned int
可以具有0
到(2^n)-1
之间的值
现在,我们可以计算不同(烧尽的) int
类型的范围(可能的值),如下所示:
+------+---------+----------+----------+----------+-------------+-----------+ |Type |char |short int |int |long int |long long int|int pointer| +------+---------+----------+----------+----------+-------------+-----------+ |32-bit|-(2^7) to|-(2^15) to|-(2^31) to|-(2^31) to|-(2^63) to |-(2^31) to | | |+(2^7)-1 |+(2^15)-1 |+(2^31)-1 |+(2^31)-1 |+(2^63)-1 |+(2^31)-1 | +------+---------+----------+----------+----------+-------------+-----------+ |64-bit|-(2^7) to|-(2^15) to|-(2^31) to|-(2^63) to|-(2^63) to |-(2^63) to | | |+(2^7)-1 |+(2^15)-1 |+(2^31)-1 |+(2^63)-1 |+(2^63)-1 |+(2^63)-1 | +------+---------+----------+----------+----------+-------------+-----------+
此外,我们可以计算不同的unsigned int
类型的范围(可能的值),如下所示:
+------+-------+----------+-------+--------+-------------+-----------+ |Type |char |short int|int |long int|long long int|int pointer| +------+-------+---------+--------+--------+-------------+-----------+ |32-bit|0 to |0 to |0 to |0 to |0 to |0 to | | |(2^8)-1|(2^16)-1 |(2^32)-1|(2^32)-1|(2^64)-1 |(2^32)-1 | +------+-------+---------+--------+--------+-------------+-----------+ |64-bit|0 to |0 to |0 to |0 to |0 to |0 to | | |(2^8)-1|(2^16)-1 |(2^32)-1|(2^64)-1|(2^64)-1 |(2^64)-1 | +------+-------+---------+--------+--------+-------------+-----------+
最后,要了解我们如何以及为什么在32位计算机上使用8字节(64位)存储long long int
请参阅此文章 。