winnie 发表于 2009-4-25 14:14:30

PICC关于unsigned 和 signed 的几个关键问题!!

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
      //中间语句
       decfi                               //只是递减,没有判断语句!!!
       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
               //中间语句
                  decfszi                     //判断是否是0
                   goto loop

再编译这样的语句:(同样循环8次)
for(i=8;i>0;i--){
;
}
               movlw 8
               movwf   i
loop
                decfszi                               //同上编译的代码。
                goto loop
再次验证了刚才的分析。
在PICC后面加上-SIGNED_CHAR后缀,则第一个示例就正确编译出来了,更证明了刚才的分析是正确的。
代码如下:
            movlw 7
            movwfi
loop
         //中间语句
               decfi                        //递减
               btfssi,7                     //判断i的7位来判断是否为负数
               goto l94
总结:在PICC无符号编译环境下,对于递减的for语句的条件判断语句不能是>=0的形式。

最后谈谈PICC的小窍门:
在PICC默认的无符号环境下,对比如下代码:
a语句:
char i,j;
i=7;
while(1){
j=0;
i--;
if(i==0)break;
}

b语句:
char i,j;
for(i=8;i>0;i--){
j=0;
}
表面看上去,一般会认为下面的代码编译后要大一点点,因为多了j中的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等,所以在编写代码时候要特别小心!!!
页: [1]
查看完整版本: PICC关于unsigned 和 signed 的几个关键问题!!