c语言位操作的一些注意事项

c语言位操作的一些注意事项

1. 位操作尽量使用unsigned char,而不是char,否则会使你混乱

如果你使用char,那么一个普通的字符,0xe3,因为首位是1,所以当他被转换为16位长时,成了0xffffffe3,而不是我们想要的0x000000e3,因为他是一个有符号的负数。
举例如下:
#include <stdlib.h>
#include <stdio.h>

int main()
{
//    char buf[10] = {0};
    unsigned char buf[10] = {0};
    char sbuf[10] = {0};
    buf[0] = 0xe3;
    buf[1] = 0xb4;
    sbuf[0] = 0xe3;
    sbuf[1] = 0xb4;
    unsigned short pid1, pid2, pid3;
   
/*bit operations with unsigned chars*/
    printf("bit operations with unsigned chars:/n");
    pid1= (buf[0]&0x1f);
    pid2= ((buf[0]&0x1f)<<8);
    pid3= ((buf[0]&0x1f)<<8)|buf[1];
   

    printf( "pid1 = %x/n", pid1  );
    printf( "pid2 = %2x/n", pid2  );
    printf( "pid3 = %2x/n", pid3  );


/*bit operations with signed chars*/
    printf("bit operations with signed chars:/n");
    pid1= (sbuf[0]&0x1f);
    pid2= ((sbuf[0]&0x1f)<<8);
    pid3= ((sbuf[0]&0x1f)<<8)|sbuf[1];
   

    printf( "pid1 = %x/n", pid1  );
    printf( "pid2 = %2x/n", pid2  );
    printf( "pid3 = %2x/n", pid3  );

}

结果如下:
[shaoting@serverbj6:/user/shaoting/DVB-T]$ ./a.out
bit operations with unsigned chars:
pid1 = 3
pid2 = 300
pid3 = 3b4
bit operations with signed chars:
pid1 = 3
pid2 = 300
pid3 = ffb4

可见,pid3的两次取值,因为一个是针对unsigned char的buffer,另一个是针对char的buffer而使结果不同。


2. 每次操作最好用括号括起来,不要随意猜想其算术优先级
位操作的优先级比算数运算优先级低,如果记不清楚,就将其括起来,不要想当然,例子:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    unsigned char buf[10] = {0};
    buf[0] = 0xf0;
    buf[1] = 0x03;
    unsigned short pid3, pid4;
   
    pid3= 5+ ((buf[0]&0x0f)<<8)|buf[1];
    pid4 =5+ (((buf[0]&0x0f)<<8)|buf[1]);

   

    printf( "pid3 = %2x/n", pid3  );
    printf( "pid4 = %2x/n", pid4  );
   
}

结果:
[shaoting@serverbj6:/user/shaoting/DVB-T]$ ./a.out
pid3 =  7
pid4 =  8

可见,我们以为pid3和pid4结果应该是一样的,都是8,但我们错了,pid3的计算结果其实是等于
(5+ ((buf[0]&0x0f)<<8))|buf[1],即先进行了加法计算,在进行了位与计算。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值