int :
32位int数据类型可以包含-2,147,483,648到2,147,483,647范围内的整数值 . 您也可以将此数据类型称为signed int或signed .
unsigned int :
32位无符号int数据类型可以包含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 . 我有点困惑 .
9 回答
问题是你调用了Undefined Behaviour .
当你调用 UB 时,任何事情都可能发生 .
作业还可以;第一行有一个隐式转换
但是,对
printf
的调用还不行是 UB 与
%
说明符和参数类型不匹配 .在您的情况下,通过提供1
int
,1unsigned int
,1int
和1unsigned int
,按此顺序指定2int
s和2unsigned int
s .不要 UB !
int
和unsigned int
的内部表示是相同的 .因此,当您将相同的格式字符串传递给
printf
时,它将被打印为相同 .但是,比较它们时存在差异 . 考虑:
这也可以是一个警告,因为在比较有符号和无符号整数时,其中一个将被隐式地转换为匹配类型 .
他在问真正的区别 . 当您谈论未定义的行为时,您处于语言规范提供的保证级别 - 它在您最喜欢的编译器上完美定义's far from reality. To understand the real difference please check this snippet (of course this is UB but it':
该类型只是告诉你比特模式应该代表什么 . 这些比特只是你对它们所做的 . 相同的序列可以用不同的方式解释 .
printf
函数根据匹配位置中的格式说明符解释传递它的值 . 如果你告诉printf
你传递int
,但是传递unsigned
,printf
将重新解释为另一个,并打印你看到的结果 .呵呵 . 你在这里有一个隐式演员,因为你告诉
printf
期望什么类型 .请尝试使用此尺寸代替:
是的,因为在你的情况下他们使用the same representation .
当解释为32b有符号整数时,位模式
0xFFFFFFFF
看起来像-1,当解释为32b无符号整数时,位模式看起来像4294967295 .它与
char c = 65
相同 . 如果将其解释为有符号整数,则为's 65. If you interpret it as a character it' sa
.由于R和pmg指出,从技术上讲,传递与格式说明符不匹配的参数是未定义的行为 . 所以程序可以做任何事情(从打印随机值到崩溃,打印“正确”的东西等) .
该标准指出
7.19.6.1-9
它们如何存储在内存和寄存器中没有区别,没有有符号和无符号版本的int寄存器没有用int存储的签名信息,差异只在执行数学运算时变得相关,有内置于CPU中的数学运算的有符号和无符号版本,签名告诉编译器使用哪个版本 .
这个很直接 . 二进制表示是它被提及但从未显示的键 . 如果0XFFFFFFF =机器代码= 1111 1111 1111 1111 1111 1111 1111 1111 = 4,294,967,295 数字的正表示,则在HEX中无符号 . 这一切都很好,但我们需要一种方法来表示负数 . 所以大脑决定两个补码 . 这意味着什么,简而言之,他们取最左边的数字,并决定当它是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 所以我想简而言之,我们可以说差异是允许负数而另一个不允许,这是由于 sign bit 或最左位或最高位 .