什么是整数文字类型? 以及他们如何存储?

我刚刚开始学习C,现在有一个问题让我烦恼了一段时间。 如果我写

int i = -1; unsigned int j = 2; unsigned int k = -2; 

整数文字-12-2的类型是什么,它如何转换为存储在signed intunsigned int

有符号整数是什么意思,变量或整数字的属性呢? 像-2是有符号整数, 2是无符号整数?

首先, -1不是整数常量。 它是一个由一元运算符组成的表达式-运算符应用于常量1

在C99和C11中,十进制整数常量的类型是intlong intlong long int中的第一个,其值适合。 类似地,八进制或hex文字具有intunsigned intlong intunsigned long intlong long intunsigned 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; 

2int类型。 它从int转换为unsigned int

 unsigned int k = -2; 

-2int类型。 它从int转换为unsigned int 。 这一次,因为-2超出了unsigned int的范围,所以转换是非平凡的; 结果是UINT_MAX - 1

一些术语:

常量是其他一些语言所谓的文字 。 它是表示常量值的单个标记。 示例是10xff

常量表达式是在编译时需要计算的表达式。 常量是常量表达式; 所以是一个表达式,其操作数是常量或常量表达式。 例子是-12+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等的类型是intlong intlong 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 intlong 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表示:

如果没有后缀,整数将与intlong intlong long intunsigned intunsigned long intunsigned 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) intunsigned 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) intunsigned 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请参阅此文章 。