我刚刚开始学习C,现在有一个问题让我烦恼了一段时间。如果我写
int i = -1;
unsigned int j = 2;
unsigned int k = -2;
整数文字-1
和2
以及-2
的类型是什么,以及它如何转换为存储在signed int
和unsigned int
中?
有符号整数是什么意思,也就是变量或整数字面的属性呢?像-2
是有符号整数,2
是无符号整数吗?
答案 0 :(得分:3)
首先,-1
不是整数常量。它是由应用于常量-
的一元1
运算符组成的表达式。
在C99和C11中,十进制整数常量的类型是其值适合的int
,long int
或long long int
中的第一个。类似地,八进制或十六进制文字具有类型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
。
一些术语:
常量是其他一些语言称为 literal 的内容。它是表示常量值的单个标记。示例包括1
和0xff
。
常量表达式是在编译时需要进行求值的表达式。常量是一个常量表达式;所以是一个表达式,其操作数是常量或常量表达式。示例包括-1
和2+2
。
答案 1 :(得分:0)
如果要指定整数的类型,可以使用integer constant:
您可以使用十进制,八进制或六进制表示写整数:
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;
如果没有后缀,整数将与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;
u与十进制表示没有区别。 l或L和ll或LL添加无符号值类型。
这类似于string literals。
答案 2 :(得分:0)
整数文字-1和2和-2的类型是什么,它如何转换为存储在signed int和unsigned int中?
C语言分析器/编译器,如前面chux所说,"理解"你的文字作为有符号整数 - 总是。然后将它们转换为适合您指定的变量,可以是不同类型的变量。这样做,一些位可能会丢失或者可能会改变它们的含义(例如,为无符号整数赋值)。有些编译器可能会警告你关于"字面超出范围",其他编译器可以默默地接受(并截断)你的文字。
你的意思是Signed Integer,也就是变量或整数字的属性,比如-2是有符号整数,2是无符号整数。?
它是变量的属性。实际上,它是一种"类型" - 写成"两个字"标识符
答案 3 :(得分:0)
我想说这取决于编译器和机器的架构。给定8 bits = 1 byte
,下表总结了32位和64位计算机上(签名)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 |
+------+------+---------+-------+--------+-------------+-----------+
正如您所知,(签名)int
和unsigned int
之间的最大区别在于(签名)int
最高位(MSB)保留用于签名整数因此:
int
的值可以介于-(2^(n-1))
到(2^(n-1))-1
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
,请参阅this post。