INT :
32位int数据类型可以包含范围内的整数值 -2,147,483,648至2,147,483,647。您也可以参考此数据类型 签名为int或签名。
unsigned int :
32位无符号整数数据 type可以保存0到4,294,967,295范围内的整数值。您 也可以将此数据类型简称为无符号。
好的,但是,在实践中:
int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;
printf("%d, %d, %u, %u", x, y, x, y);
// -1, -1, 4294967295, 4294967295
没有区别,O.o。我有点困惑。
答案 0 :(得分:44)
鹤鹤。你有一个隐式演员,因为你告诉printf
期待什么类型。
尝试使用此尺寸代替:
unsigned int x = 0xFFFFFFFF;
int y = 0xFFFFFFFF;
if (x < 0)
printf("one\n");
else
printf("two\n");
if (y < 0)
printf("three\n");
else
printf("four\n");
答案 1 :(得分:24)
是的,因为在您的情况下,他们使用the same representation。
当解释为32b有符号整数时,位模式0xFFFFFFFF
看起来像-1,当解释为32b无符号整数时,位模式看起来像4294967295。
与char c = 65
相同。如果你把它解释为有符号整数,它就是65.如果你把它解释为一个字符a
。
由于R和pmg指出,从技术上讲,传递与格式说明符不匹配的参数是未定义的行为。所以程序可以做任何事情(从打印随机值到崩溃,打印“正确”的东西等)。
标准指出7.19.6.1-9
如果转换规范无效,则行为未定义。 如果 任何参数都不是相应转换的正确类型 具体而言,这种行为是未定的。
答案 2 :(得分:16)
两者在内存和寄存器中的存储方式没有区别,没有有符号和无符号版本的int寄存器,没有用int存储的签名信息,差异只在执行数学运算时才变得相关,内置于CPU中的数学操作符号和未签名版本,签名告诉编译器使用哪个版本。
答案 3 :(得分:7)
问题是您调用了Undefined Behaviour。
当您调用 UB 时,可能会发生任何事情。
作业没问题;在第一行中存在隐式转换
int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;
但是,对printf
的调用不正常
printf("%d, %d, %u, %u", x, y, x, y);
UB 与%
说明符和参数类型不匹配。
在您的情况下,您可以按此顺序指定2个int
和2个unsigned int
,提供1个int
,1个unsigned int
,1个int
和1个{{ 1}}。
不要 UB !
答案 4 :(得分:3)
int
和unsigned int
的内部表示相同。
因此,当您将相同的格式字符串传递给printf
时,它将被打印为相同的格式。
但是,比较它们时会有所不同。 考虑一下:
int x = 0x7FFFFFFF;
int y = 0xFFFFFFFF;
x < y // false
x > y // true
(unsigned int) x < (unsigned int y) // true
(unsigned int) x > (unsigned int y) // false
这也可以是一个警告,因为在比较有符号和无符号整数时,其中一个将被隐式地转换为匹配类型。
答案 5 :(得分:2)
他在询问真正的差异。 当你谈论未定义的行为时,你处于语言规范提供的保证级别 - 它远非现实。 要了解真正的区别,请检查此片段(当然这是UB,但它在您最喜欢的编译器上完美定义):
#include <stdio.h>
int main()
{
int i1 = ~0;
int i2 = i1 >> 1;
unsigned u1 = ~0;
unsigned u2 = u1 >> 1;
printf("int : %X -> %X\n", i1, i2);
printf("unsigned int: %X -> %X\n", u1, u2);
}
答案 6 :(得分:1)
该类型只是告诉您应该表示的位模式。这些比特只是你对它们所做的。相同的序列可以用不同的方式解释。
答案 7 :(得分:1)
printf
函数根据匹配位置的格式说明符解释传递的值。如果您告诉printf
您传递的是int
,而是传递unsigned
,printf
会将其重新解释为另一个,并打印您看到的结果。< / p>
答案 8 :(得分:0)
这个很直接。二进制表示是它被提及但从未显示的键。 在HEX中无符号,如果0XFFFFFFF =机器代码= 1111 1111 1111 1111 1111 1111 1111 1111 = 4,294,967,295 数字的正表示。 这一切都很好,但我们需要一种方法来表示负数。 所以大脑决定两个补码。 这意味着什么呢,简而言之,他们取最左边的数字并决定当它是1(然后是所有的直到你到达最左边的最高位),如果它是0则数字将为负数。 现在让我们来看看 0000 0000 0000 0000 0000 0000 0000 0011 = 3 会发生什么。 现在让我们继续增加这个数字 0111 1111 1111 1111 1111 1111 1111 1111 = 2,147,483,645 带有signed int的最高正数。 让我们加1(这里你可能想要查找二进制加法) 我们必须一直带着这一个。 1111 1111 1111 1111 1111 1111 1111 1110 = -1 所以我想简而言之,我们可以说区别是允许负数而另一个不允许,这是由于符号位或最左位或最高位。