1

在计算有符号和无符号的 char、short、int 和 long 变量范围的过程中,我采用了以下解决方案:

  1. https://stackoverflow.com/a/19085193/11320006

  2. http://www.learntosolveit.com/cprogramming/Ex_2.1_cal_limits.html

根据解决方案 1,我希望在下面的代码中输出 -1 和 65535,假设它的行为与两个格式说明符的代码(unsigned short)~0相同。(unsigned int)~0

// the two statements below produce different results
printf("Value of unsigned int is %d\n", (unsigned int)~0); // outputs -1                                                                                                                                                     
printf("Value of unsigned int is %u\n", (unsigned int)~0); // outputs 4294967295

// whereas, the two statements below produce the same result. Why?
printf("Value of short unsigned int is %d\n", (unsigned short)~0); // outputs 65535, expected -1
printf("Value short unsigned int is %u\n", (unsigned short)~0); // outputs 65535

(unsigned short)~0为什么和的行为有所不同(unsigned int)~0

4

2 回答 2

3

(unsigned short)~0为什么和的行为有所不同(unsigned int)~0

这些表达式的行为是类似的。假设 type 的二进制补码表示int,每个都计算其(无符号)类型的最大可表示值。

但是,可变参数函数的可变参数(例如)printf受默认参数提升的约束。这会影响unsigned short,将其提升为intifint可以代表所有unsigned short值,就像您的示例中的情况一样(以及unsigned int其他情况)。它不影响 or 类型的参数intunsigned int或更宽的整数类型。

所呈现代码的关键问题是......

printf("Value of unsigned int is %d\n", (unsigned int)~0);

%d... 由于指令与相应参数的类型不正确匹配,因此 表现出未定义的行为。%d必须与已签名 int的 匹配,但您已将其与unsigned int. 在实践中,UB 表现为将参数的位模式解释为好像它是 asigned int而不是无符号的,但原则上,程序可以在其能力范围内做任何事情。

请注意,由于类型不匹配,这也具有未定义的行为:

printf("Value short unsigned int is %u\n", (unsigned short)~0);

该指令%hu将是与相应实际参数的最佳匹配,但%d由于上述自动类型提升,该指令是可以接受的。 %u不匹配。然而,在这种情况下,显示的 UB 与您预期的行为相同——至少就输出所指示的而言。在实践中,非负signed int参数的位模式已被解释为unsigned int.

于 2020-10-12T17:13:43.757 回答
1

很简单 - 因为您使用了错误的 printf 格式。

int main(void)
{
    printf("Value of short unsigned int is %hd\n", (unsigned short)~0); 
    printf("Value short unsigned int is %hu\n", (unsigned short)~0); 

    printf("Value of short unsigned int is %hhd\n", (unsigned char)~0); 
    printf("Value short unsigned int is %hhu\n", (unsigned char)~0); 
}

记住

使用 printf 系列函数时始终使用正确的格式!!!。使用错误的可能会导致未定义的行为

于 2020-10-12T17:04:50.180 回答