@Ganesh,
在这种情况下编译器不会产生错误。
C 语言给你极大的力量,但你需要小心。使用“无符号”关键字告诉编译器如何处理 MSB(最高有效位)。更准确地说,当您将“int”类型的变量分配给内存位置时,它将在内存中保留一些空间(取决于平台)。为简单起见,假设 int 保留了 8 位内存,因此:1 2 3 4 5 6 7 8。每个数字代表一个字节(8 个系列)中的一个位(可以保存 0 或 1 的单个内存位置)位)。当您声明:有符号整数并输入:
signed int a = -1;
编译器会这样做:1 0 0 0 _ 0 0 0 1(_ 只是为了让数字序列更易于阅读)。
这不会被解读为一个非常大的数字。这将被读取为“负 1”,因为最高有效位(从左到右读取的第一位)将被读取为符号。这意味着有符号的 int 值仅使用 7 位(在此示例中)来存储数字的值,而一位将用于存储符号(0 表示数字为正数,1 表示数字为负数)。
“无符号”关键字有什么作用?
当你告诉编译器时:
unsigned int a = 1;
它完全改变了数字的读取方式。还记得那个记忆位置:1 2 3 4 5 6 7 8 吗?好吧,位置 1 的位将不再能够存储数字的符号。这意味着所有八位都将用于存储数字的值。
在二进制情况下:1 0 0 0 _ 0 0 0 1 作为有符号整数将被读取为 -1,但作为无符号值,它会很大(您可以使用 bin 到 dec 转换器查看确切的数字在线,但这不是重点)。
那么,您的代码有什么问题?第一个是:
(1) unsigned int a = -1;
第二个是:
(2) printf ("%d", a);
那么,我们来谈谈为什么第一条语句不会导致代码崩溃?
C 世界基于汇编指令(暂时不管它们是什么),它完全是二进制的。
C 真的不在乎数字。它们只是为了帮助程序员编写可读的程序。
当你指定-1时,不管它是什么类型的数据,内存:1 2 3 4 5 6 7 8 将被填充为:
1 2 3 4 .. 5 6 7 8
1 0 0 0 .. 0 0 0 1
故事结束。编译器按以下顺序操作:
(1) 关键字(int, float, ...):为变量预留空间
(2) 值 (-1):转换为二进制字
(3) 故事结束。
当编译器转换字面量(数字如:-1、60、2.63262 等)时,如果出现“-”符号,它将始终将 MSB 分配为:1(再次说明:MSB 为 x 2 3 4 5 6 7 8,x 位置)。在 gcc 上使用 -Wall 等编译器指令:
gcc -Wall test.c -o test.o
会给你所有的警告:“我希望得到这个,但我得到了这个”。警告可能是你最好的朋友,但我发现它们通常比受益者更邪恶。
你甚至可以说:
int a = 5.125;
这是一个浮点数,但编译器不会争论(可能会出现警告,但不会出错)。
我认为这说明了一些原因:
unsigned int a = -1;
可以通过编译器。
第二件事是“printf”。这可能是检查变量持有什么值的最糟糕的方法,因为您可以看到您将 -1 分配给无符号变量,然后将其读出为 -1。
就是这样:1 0 0 0 _ 0 0 0 1 对计算机没有任何意义。这只是一系列信息(电压的高/低值),但计算机对于其他一切都是愚蠢的。程序可以让计算机理解这些信息的含义。
当你说:printf("%d", a), using %d spaceholder,你是在说:好的,把存储在变量“a”中的信息给我。计算机得到: 1 0 0 0 _ 0 0 0 1。正如我所说,计算机对其他一切一无所知。它无法理解这些电压系列(以数字表示)的含义。
这就是 %d 出现的地方。它告诉计算机:好的,读取二进制值,其中第 1 位是符号值,并将剩余的(7 位)转换为十进制数,然后在终端上打印出来(那个黑框你会看到打印的数字/如果你使用的是 Windows,它被称为命令提示符)。
因此,%d 是一个空格符,它告诉获取的数字将被解释为符号的值。这就是为什么:
unsigned int a = -1;
>> -1
打印出 -1。
但是,如果您要使用,正如 pmg 所提到的,%u spaceholder,那么它会告诉编译器将:1 0 0 0 _ 0 0 0 1 消息视为没有任何位的数字代表一个数字的符号,因此,您会打印出类似 6316136236136 的内容(好吧,不是那么大,但您可能明白了)。
总结这一点,相当冗长,
(1) C语言中变量类型要注意,要保持一致;
(2) 密切注意 printf 空间持有者,因为它们会以不同的方式解释值,例如:
float a = 5.125;
printf("%f", a);
>> 5.1250
printf("%d", a);
>> god knows what number you'll get (I just got: 1508905080)
我希望这些信息能够引导您走上正确的道路。您可以发表评论,我会尽快联系您。