嘿,我对 C 有点陌生,我想问为什么会打印出来4
而不是260
?
#include <stdio.h>
int main()
{
unsigned char x = 130;
x *= 2;
printf("%d\n", x);
}
嘿,我对 C 有点陌生,我想问为什么会打印出来4
而不是260
?
#include <stdio.h>
int main()
{
unsigned char x = 130;
x *= 2;
printf("%d\n", x);
}
该*=
运算符称为乘法赋值运算符,是左侧操作数与右侧操作数相乘并将结果分配给左侧操作数的简写。在这种情况下,它与以下内容相同:
x = x * 2;
这里首先发生整数提升x * 2
,结果确实是260
。
但是,anunsigned char
通常只能携带 0 到 255(含)之间的值,因此当您尝试分配高于 255 和 260 % 256 == 4 的值时,结果会溢出(回绕)。
x *= 2
使用乘法赋值运算符x = x * 2
,这是where的简写符号,x
只计算一次。
这个小程序的行为很重要:
x
被提升为130
类型int
,并且乘法给出260
了int
.unsigned char
通过重复减去UCHAR_MAX+1
(系统上的 256)转换为目标类型,直到达到目标类型范围内的值。因此x
变为 260 % 256 = 4。int
,所以在传递给 时x
被提升为,所以格式,它需要一个值,定义了行为并产生。int
printf
%d
int
4
请注意,对于unsigned char
具有超过 8 位的奇异架构(例如:数字信号处理芯片),上面的一些讨论是无关紧要的,并且printf
可能会打印260
甚至具有未定义的行为(如果sizeof(int) == 1
)。
在带有复合赋值运算符的语句中
x*=2;
相当于
x = x * 2;
由于整数提升,表达式的操作数x
被转换为类型int
,结果 pf 表达式确实等于 260。但结果被分配给类型为 unsigned char 的变量 x。
unsigned char x=130;
值 260 不能存储在这样的对象中。由于 260 在内部是一个整数,因此表示为
0x00000104
然后只有最后一个值为 0x4 的字节存储在对象中,并输出该值。
例如,如果变量 x 的类型至少会改变,您可以获得预期的结果
unsigned short x=130;
根据语言规范,无符号字符数据类型占用 1 个字节的内存,因此它可以存储 0-255 的值,如果您的值大于 255,它将从零开始溢出。所以 260(130 * 2) - 256 = 4 被分配给你的变量。 https://docs.microsoft.com/en-us/cpp/cpp/cpp-type-system-modern-cpp?view=msvc-170#fundamental-built-in-types
unsigned char
只能包含从 0 到 256。当该值超过 256 时,该值强制从 0 到 256 。