现在的位置: 首页 > 综合 > 正文

C语言常见错误

2018年02月15日 ⁄ 综合 ⁄ 共 1099字 ⁄ 字号 评论关闭

1. 有符号和无符号数的差别

   a. 对无符号数,永远不要加小于零的判断

    unsigned int i=-1;

    if(i<0)

   {

      xxxx;

   }

   上面if语句里永远执行不到。

  b. 指针和有符号数相加

    unsigned char ccc;

    unsigned char offset_table[256] = {0,1,2,3,4,.........253,254,255};

    char p[] = {0x89,0x88,0x87,0x86,0x85,0x84,0x83};

    c = offset_table(p[1]);

    c并不是从offset中查出来的,因为c是有符号的,其实上面的c值是   *(offset_table+0xffffff88).

    看看汇编就明白了,一个同事处理网络上接受的数据,判断数据的时候出现了这个错误,她的代码比上面的

    还复杂,而且是一系列的宏定义的,和其他逻辑交织在一起,害的我帮她查了好一会儿才。正确的做法是

    把p定义为unsigned char p[],。

  c. 不要小看某个函数未声明的编译警告

     "warning,  get_page_width undefined, assuming extern returning int"

     这个警告很多人不注意,编译器认为是返回int型的,就会有上面b提到的问题,同时,如果函数

    get_page_width()在函数实体的地方返回值定义为short  get_page_width()(或

    char get_page_width() ),那么函数返回的地方在汇编里eax寄存器的高16位可能是不是0,或随机的

    值,假设高16的值是0xffff, get_page_width值是1,高 那么int i = get_page_width(), i的值就是

    0xffff0001, 显然不是你想要的值。

符号转换的含义

以前以为都是尽量的多打括号,多转换,再看别人的定点浮点转换发现的bug。

u32 v = 0x7FFF7FFF;
s32 coord0 = ((s16)((v&0x3FF)<<6))>>6;
则coord0 = –1; 会进行符号位的扩展。s16会强制(v&0x3FF)<<6是16位符号数,所以再右移的时候会按着s16t进行符号扩展移位。

u32 v = 0xF000FFFF; s16 co = v>>20;
则co = 0x0F00; 不会进行符号位的扩展。

short  c = 0x0FFF;
  int i = (c<<8);

则i = 0x000FFF00

short  c = 0x0FFF;
  int i = (short)(c<<8);

则i = 0xFFFFFF00

抱歉!评论已关闭.