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
Run Code Online (Sandbox Code Playgroud)
没有区别,噢我有点困惑.
cha*_*ite 46
呵呵.你在这里有一个隐式转换,因为你告诉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");
Run Code Online (Sandbox Code Playgroud)
cni*_*tar 24
是的,因为在您的情况下,他们使用相同的表示.
0xFFFFFFFF
当解释为32b有符号整数时,位模式看起来像-1,当解释为32b无符号整数时,位模式看起来像4294967295.
它是一样的char c = 65
.如果你把它解释为有符号整数,它就是65.如果你将它解释为一个字符a
.
由于R和pmg指出,从技术上讲,传递与格式说明符不匹配的参数是未定义的行为.所以程序可以做任何事情(从打印随机值到崩溃,打印"正确"的东西等).
该标准指出了它 7.19.6.1-9
如果转换规范无效,则行为未定义.如果任何参数不是相应转换规范的正确类型,则行为未定义.
Nat*_*Day 18
它们如何存储在内存和寄存器中没有区别,没有有符号和无符号版本的int寄存器没有用int存储的签名信息,差异只在执行数学运算时变得相关,有内置于CPU中的数学运算的有符号和无符号版本,签名告诉编译器使用哪个版本.
问题是您调用了未定义的行为.
当你调用UB时,任何事情都可能发生.
作业还可以; 第一行有一个隐式转换
int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;
Run Code Online (Sandbox Code Playgroud)
但是,打电话printf
,不行
printf("%d, %d, %u, %u", x, y, x, y);
Run Code Online (Sandbox Code Playgroud)
这是UB失配的%
说明符和参数的类型.
你的情况您指定2 int
秒和2 unsigned int
的顺序,提供1秒int
,1 unsigned int
,1 int
,和1 unsigned int
.
不要做UB!
的内部表示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
Run Code Online (Sandbox Code Playgroud)
这也可能是一个警告,因为在比较有符号和无符号整数时,其中一个将被隐式转换以匹配类型。
二进制表示是关键。示例:十六进制形式的无符号整数
0XFFFFFFF = translates to = 1111 1111 1111 1111 1111 1111 1111 1111
Run Code Online (Sandbox Code Playgroud)
它代表 4,294,967,295
以十为基数的正数。但我们还需要一种表示负数的方法。所以大脑决定使用二进制补码。简而言之,他们取了最左边的位,并决定当它为 1(后面至少有一个其他位设置为 1)时,该数字将为负数。最左边的位设置为 0 表示数字为正数。现在让我们看看会发生什么
0000 0000 0000 0000 0000 0000 0000 0011 = 3
Run Code Online (Sandbox Code Playgroud)
加上我们最终达到的数字。
0111 1111 1111 1111 1111 1111 1111 1111 = 2,147,483,645
Run Code Online (Sandbox Code Playgroud)
带符号整数的最大正数。让我们再添加 1 位(二进制加法将溢出带到左侧,在这种情况下,所有位都设置为 1,因此我们落在最左边的位)
1111 1111 1111 1111 1111 1111 1111 1111 = -1
Run Code Online (Sandbox Code Playgroud)
所以我想简而言之,我们可以说区别在于一个允许负数,另一个则不允许。因为符号位或最左边位或最高有效位。