位操作及其使用注意事项,C语言位操作及其使用方法详解
我们知道,程序中的所有数据在计算机内存中都是以二进制的形式进行存储的,数据的位是可以操作的最小数据单位,位操作就是直接对整数在内存中的二进制位进行操作。因此,在理论上,我们可以通过“位运算”来完成所有的运算和操作,从而有效地提高程序运行的效率。
C 语言中提供了 &(与)、|(或)、^(异或)、~(取反)、>>(右移)、<<(左移)6 种位操作符。我们可以在程序中合理地使用这些位操作符号来提高程序的运行效率,例如,对于下面的示例代码:
int x=0; int y=0; x = 257 /8; y = 456 % 32;
我们可以通过位操作符将其修改成如下形式:
int x=0; int y=0; x = 257 >>3; y = 456 - (456 >> 4 << 4);
这样就可以使程序在性能上得到一定提升。
尽量避免对未知的有符号数执行位操作
在 C 语言中,如果在未知的有符号数上执行位操作,很可能会导致缓冲区溢出,从而在某些情况下导致攻击者执行任意代码,同时,还可能会出现出乎意料的行为或编译器定义的行为。
下面来看一个简单的示例:
#include <stdio.h> int main (void) { int x=0; int y=0x80000000; char buf[sizeof("128")]; x=sprintf(buf,"%u",y>>24); if(x==-1||x>=sizeof(buf)) { // 错误处理 } printf(buf); return 0; }
代码中,y>>24 的执行结果为 4294967168,而 sizeof(buf) 的结果为 4。当我们将 y>>24 的结果值转换为字符串“4294967168”时,超出了 buf 范围,所以结果值无法完全存储在 buf 中。因此,在执行语句“x=sprintf(buf,"%u",y>>24)”时,sprintf 方法在进行写操作时就会越过 buf 的边界,从而产生缓冲区溢出。
如果在编译器 VC++ 中执行这段程序,将会产生如图 1 所示的错误报告。
发表评论