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

时间:2016-12-31 04:53:02

标签: c constants signed unsigned-integer

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

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

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

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

4 个答案:

答案 0 :(得分:3)

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

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

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

unsigned int k = -2;

-2的类型为int。它已从int转换为unsigned int。这一次,由于-2超出了unsigned int的范围,因此转换非常重要;结果是UINT_MAX - 1

一些术语:

常量是其他一些语言称为 literal 的内容。它是表示常量值的单个标记。示例包括10xff

常量表达式是在编译时需要进行求值的表达式。常量是一个常量表达式;所以是一个表达式,其操作数是常量或常量表达式。示例包括-12+2

答案 1 :(得分:0)

在C99和C11

如果要指定整数的类型,可以使用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等的类型为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;

八进制和十六进制表示:

如果没有后缀,整数将与intlong intlong long intunsigned intunsigned long intunsigned 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位计算机上(签名)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    | 
+------+------+---------+-------+--------+-------------+-----------+

正如您所知,(签名)intunsigned int之间的最大区别在于(签名)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,请参阅this post