今天在看《C程序设计语言》的时候写了如下一段代码
int main(void) { unsigned int a = -20; printf("%d", a); return EXIT_SUCCESS; }
Console: -20
理论上a声明为unsigned int后不应该能显示正确的值,这里之所以能显示-20是由于在printf的格式化参数中使用了%d, 该函数会首先将a转化为int类型。
如果你对编译器的越界处理有所了解的话,应该知道这时候一般情况下,a所表示的值为4294967276(在32位机器中,int用32位bit来表示,无符号int所能表示的最大数为4294967296)
说说我所理解的编译器对上述代码的处理:
1. -20为int类型,第2行赋值语句将它强行转化为unsigned int类型, 越界,因为unsigned int和int在内存中存储的位数是一样的,因此两者在物理内存中是完全一样的。
2. 第3行printf遇到%d占位符时,即认为此处应显示一个int类型值, 于是将a又转化为int类型,所以此时显示出来的结果跟原来赋值是一样的
要想显示无符号整型值,需要使用%u占位符