|
unsigned 是表示一个变量(或常数)是无符号类型。signed表示有符号。
它们表示数值范围不一样。
PICC默认所有变量都是unsigned类型的,哪怕你用了signed 变量。因为有符号运算比无符号运算耗资源,而且MCU运算一般不涉及有符号运算。
在PICC后面加上-SIGNED_CHAR后缀可以告诉PICC把signed变量当作有符号处理。
在PICC默认的无符号运算下看这样的语句:
char i;
for(i=7;i>=0;i--){
; //中间语句
}
这样的C代码看上去是没有丁点错误的,但编译后,问题出现了:
movlw 7
movwf i
loop
//中间语句
decf i //只是递减,没有判断语句!!!
goto loop
原因是当i是0时候,条件还成立,还得循环一次,直到i成负1条件才不成立。而PICC在默认参数下是不能判断负数的,所以编译过程出现问题。
那么采用这样的语句来验证:
char i;
i=7;
while(1){
i--;
//中间语句
if(i==0)break; //告诉PICC以判断i是否是0来作为条件
}
编译后代码正确:
movlw 7
movwf i
loop
//中间语句
decfsz i //判断是否是0
goto loop
再编译这样的语句:(同样循环8次)
for(i=8;i>0;i--){
;
}
movlw 8
movwf i
loop
decfsz i //同上编译的代码。
goto loop
再次验证了刚才的分析。
在PICC后面加上-SIGNED_CHAR后缀,则第一个示例就正确编译出来了,更证明了刚才的分析是正确的。
代码如下:
movlw 7
movwf i
loop
//中间语句
decf i //递减
btfss i,7 //判断i的7位来判断是否为负数
goto l94
总结:在PICC无符号编译环境下,对于递减的for语句的条件判断语句不能是>=0的形式。
最后谈谈PICC的小窍门:
在PICC默认的无符号环境下,对比如下代码:
a语句:
char i,j[8];
i=7;
while(1){
j=0;
i--;
if(i==0)break;
}
b语句:
char i,j[8];
for(i=8;i>0;i--){
j[i-1]=0;
}
表面看上去,一般会认为下面的代码编译后要大一点点,因为多了j[i-1]中的i-1。
其实编译后代码量是一摸一样的。
原因如下:
movlw 8或7 //a语句是7,b语句是8
movf i
loop
//a语句在这里提取i给j数组
//i 递减判断语句
//b语句在这里提取i给j数组
goto loop
可以看出只是代码位置不同而已,并没添加代码量。b语句同样达到了从7到0的循环。
小总结:对于递减到0的for语句推荐用>0判断语句来实现,不会出现编译错误的问题,并且不会增加代码量,尤其对于数组操作的方面。
另:对于PICC或CCS,在其默认的无符号编译环境下,如果出现负数运算就会出问题。
如(-100)+50等,所以在编写代码时候要特别小心!!! |
|