C语言易错知识点——无符号数和有符号数的大小比较
我们来看两串代码
代码一:
#include<stdio.h> int main() { int a = -1; if (a > sizeof(int)) { printf(">\n"); } else { printf("<\n"); } return 0; }
代码二:
#include<stdio.h> #include<string.h> int main() { if (strlen("abc") - strlen("abcdef") > 0) { printf("SUCCESS\n"); } else { printf("ERROT\n"); } return 0; }
分析:
我们来看看这两串代码的结果:
是不是和大家想象的结果截然相反?sizeof(int) = 4
,这么会比-1还小呢?strlen("abc") = 3,strlen("abcdef") = 6
,3 - 6怎么还大于0呢?
- 要搞清楚为什么,我们就需要明白两点:
- 操作符
sizeof()
和字符串函数strlen()
的返回值都是无符号整型size_t
- 当无符号数和有符号数比较时,我们要先将有符号数看成无符号数(即将有符号数在内存中的二进制码的符号位看成有效数字位),再进行计算
- 现在我们来看第一题:a是一个有符号int型整型,在内存中的二进制补码为:
1111 1111 1111 1111 1111 1111 1111 1111
,由于是将这个有符号数和无符号数比较,因此我们就要将这个二进制码的符号位看成有效数字位,此时-1就转换为了4,294,967,295
这么大的数字(实际上就是UINT_MAX
),那么显然,打印的就是>了。
- 再来看第二题:
strlen("abc") - strlen("abcdef")
得到的结果是-3,在内存中的补码为:1111 1111 1111 1111 1111 1111 1111 1101
,但这是一个无符号数,我们要将它的符号位看成有效数字位,此时-3就转化成了4294967293
这样一个数,显然大于0。
总结
无符号数和有符号数的比较在C语言中是一个大陷阱,稍不注意就会将很多代码理解错误,当碰到返回类型为无符号数的操作符或函数时,我们一定要小心又小心,注意它和整数的比较,避免犯错。