1

嘿,我对 C 有点陌生,我想问为什么会打印出来4而不是260?

#include <stdio.h>

int main()
{
    unsigned char x = 130;
    x *= 2;
    printf("%d\n", x);
}
4

5 回答 5

3

*=运算符称为乘法赋值运算符,是左侧操作数与右侧操作数相乘并将结果分配给左侧操作数的简写。在这种情况下,它与以下内容相同:

x = x * 2;

这里首先发生整数提升x * 2,结果确实是260

但是,anunsigned char通常只能携带 0 到 255(含)之间的值,因此当您尝试分配高于 255 和 260 % 256 == 4 的值时,结果会溢出(回绕)。

于 2022-01-30T14:28:02.180 回答
3

x *= 2使用乘法赋值运算符x = x * 2,这是where的简写符号,x只计算一次。

这个小程序的行为很重要:

  • 乘法是在参数的整数提升之后执行的,这意味着 , 的值x被提升为130类型int,并且乘法给出260int.
  • 该值unsigned char通过重复减去UCHAR_MAX+1(系统上的 256)转换为目标类型,直到达到目标类型范围内的值。因此x变为 260 % 256 = 4。
  • 因为它有一个小于 的整数类型int,所以在传递给 时x被提升为,所以格式,它需要一个值,定义了行为并产生。intprintf%dint4

请注意,对于unsigned char具有超过 8 位的奇异架构(例如:数字信号处理芯片),上面的一些讨论是无关紧要的,并且printf可能会打印260甚至具有未定义的行为(如果sizeof(int) == 1)。

于 2022-01-30T14:44:35.973 回答
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;
于 2022-01-30T14:43:54.413 回答
1

根据语言规范,无符号字符数据类型占用 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

于 2022-01-30T14:40:42.767 回答
0

unsigned char只能包含从 0 到 256。当该值超过 256 时,该值强制从 0 到 256 。

于 2022-01-30T14:30:48.803 回答