在STM32项目的开发过程遇到一个奇葩的问题,测试代码如下:
char _char =-1;
if(_char!=-1)
{
pr_dbg("_char!=-1\r\n");
}
else
{
pr_dbg("_char==-1\r\n");
}
结果输出:
1048 [dbg] main 83 _char!=-1
同时编译器也会给出如下警告:
..\USER\main.c(70): warning: #68-D: integer conversion resulted in a change of sign
char _char =-1;
..\USER\main.c(87): warning: #514-D: pointless comparison of unsigned integer with a negative constant
if(_char!=-1)
整数转换导致一次符号改变
“无符号整数与负常量的无意义比较”。
继续追究
signed char signed_char =-1;
char _char =-1;
pr_dbg("signed_char=%d %X\t_char=%d %X\r\n",signed_char,signed_char,_char,_char);
pr_dbg("sizof(signed char)=%d\t sizof(char)=%d\r\n",sizeof(signed_char),sizeof(_char));
if(signed_char!=-1)
{
pr_dbg("signed_char!=-1\r\n");
}
else
{
pr_dbg("signed_char==-1\r\n");
}
输出结果:
1047 [dbg] main 72 signed_char=-1 FFFFFFFF _char=255 FF
1048 [dbg] main 74 sizof(signed char)=1 sizof(char)=1
1049 [dbg] main 82 signed_char==-1
在keil 5中的编译测试结果如下:
这里就能直观的看出,汇编语言赋值的值不一样。signed_char扩展到了通用寄存器R4中,以32位的-1值存储。 而 _char却不是。
char 和signed char 两个变量并不是一样的。
总结:
1、char 在Keil编译器中被当作成了无符号的8位整数处理了。
2、char变量避免与负值算术、逻辑运算。
2、对于不同的编译器,对变量的编译处理方式有可能存在差异,建议使用统一头文件 stdint.h
3、char一般用于存储字符数据,数值常量避免使用,用signed char和unsigned char代替,stdint.h定义了int8_t和uint8_t.