最近在整理代码时,发现有一些如下类型的警告:
..\XXXXX\XXXXX.c(224): warning: #186-D: pointless comparison of unsigned integer with zero
这个警告的意思是无符号数与0比较是无意义,而我报警告的代码行如下:
char len_val = 0;
if ( len_val >= 0 && len_val < 9) // 存在警告的行
{
.......
}
这里len_val的类型是char,看起来不像是无符号的,而在C语言的教材中,一般默认char都是指有符号的,无符号的类型才会带 unsigned……百思不得其解。
为此我再次查阅了之前翻看的材料才发现,C99标准没有说明char类型是有符号还是无符号:
在头文件limits.h 说明了各种不同的整数类型的特点,同时定义了下列名字:CHAR_BIT是字符型的位数(至少8位);CHAR_MIN和CHAR_MAX定义了缺省字符类型的范围,它们或者应该与SCHAR_MIN 和 SCHAR_MAX相同,或者应该与0和UCHAR_MAX相同。
而是否相同,取决于具体实现的编译器。
也就是说,不同的编译器,对缺省的 char,要么是 signed char,要么是 unsigned char(废话,呵呵),就看编译器怎么实现的。这就意味着不同编译器的 char 可能拥有不同范围的值。那说到这里,就不得不提一下,程序的可移植性,比如说我在A编译环境中,char 是无符号的,到了B编译环境 char 就成了有符号的,那在移植后就可能会出现问题。
那怎么提高程序的移植性呢,很显然,直接显式声明是否有符号就可以了,so easy~
那我再告诉你个不幸的消息,那就是不同的编译器性格不同,有的编译器擅长处理 signed char,有的处理起 unsigned chnar 又得心应手,那么,如果把 char 硬改成 signed 或 unsigned 就可能损失效率。所以,把所有的char变量统一声明为 signed 或 unsigned 未必就是上上之选。还有些处理字符的库函数把它们的参数声明为char,如果你把参数显式声明为 unsigned char 或signed char,可能会带来兼容性问题。
这也不行 ,那又不好,那究竟要咋样?
书上的大牛说了:
将 char 型变量的值限制在 signed char 和 unsigned char 的交集内,这就可以获得最大程度的可移植性,而又不牺牲效率。并且,只有当 char 型变量显式声明为 signed 或 unsigned 时,才对它执行算术运算。
是不是很简单……哈哈……
生活就是带着镣铐跳舞,端看你的关注点在哪里,
所以,也没有必要完全按照上面的处理来,
但是,这个理论我们要知道,这就是读书的必要性!
好了,现在你知道上面为什么报这个警告了吗?
对了,我这里的的编译环境是KEIL。
是的,从这个警告你就可以推断出,这里把 char 处理成了unsigned char,只有这样才会有这个警告。
那我们来验证下:
在KEIL中通过菜单(Project->Options for Target 'XXXX')或快捷工具打开对话框,如下图所示:
看到“Plain Char is Signed”这个选项了吗,KEIL默认是不选的,不选就意味着默认的 char 型是无符号的 ,即:char = unsigned char,既然是无符号了,跟0比较,那必然是多此一啰嗦了,所以才会有上面的警告了。
所以,现在对于 “char类型到底是有符号还是无符号的”这个问题,你清楚了吧。
那就到这里吧~
感谢一起学习的XDJM,没事的时候,我们一起多啃啃专业书吧~
转载请注明出处哦~