我不小心使用“%d”使用在线编译器打印了无符号整数。我以为会出现错误,但是我的程序可以成功运行。我的代码可以运行,这很好,但我就是不明白为什么。
#include <stdio.h>
int main() {
unsigned int x = 1;
printf( "%d", x);
return 0;
}
“无符号整数”的值足够小,以至于未设置 MSB(最高有效位)。如果是, printf() 会将该值视为“负符号整数”值。
int main() {
uint32_t x = 0x5;
uint32_t y = 0xC0000000;
printf( "%d %u %d\n", x, y, y );
return 0;
}
5 3221225472 -1073741824
你可以看到差异。
使用“读入” printf 格式说明符并将其与以下参数的数据类型进行匹配的new-fangled编译器,在线编译器可能或可能无法报告这种类型不匹配警告。这可能是您想要研究的内容。
参考printf()手册,他们说:
指定要应用的转换类型的字符。这 转换说明符及其含义是:
d,我
int 参数是 转换为带符号的十进制表示法。精度(如果有的话)给出 必须出现的最少位数;如果转换后的值 需要较少的数字,它在左侧用零填充。这 默认精度为 1。当以显式精度打印 0 时 0,输出为空。
所以这意味着参数即使是
unsigned
表示形式,也会被转换为 signed int
表示形式并打印,请参阅以下代码示例:
#include <stdio.h>
int main(){
signed int x1 = -2147483648;
unsigned int x2 = -2147483648;
unsigned long long x3 = -2147483648;
printf("signed int x1 = %d\n", x1);
printf("unsigned int x2 = %d\n", x2);
printf("signed long long x3 = %d\n", x3);
}
这是输出:
signed int x1 = -2147483648
unsigned int x2 = -2147483648
signed long long x3 = -2147483648
所以这意味着无论打印的变量是什么类型,只要您指定
%d
作为格式说明符,变量就会被转换为signed int
中的表示形式并被打印
在
unsigned char
的情况下,例如:
#include <stdio.h>
int main(){
unsigned char s = -10;
printf("s = %d",s);
}
输出是:
s = 246
因为
unsigned char s = -10
的二进制表示是 :
1111 0110
其中MSB位为1,但是当它转换为
signed int
时,新的表示为:
0000 0000 0000 0000 0000 0000 1111 0110
因此 MSB 中不再有代表数字是正数还是负数的 1 位。