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);这样就可以使程序在性能上得到一定提升。
#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 的边界,从而产生缓冲区溢出。
图 1
int y=0x80000000;修改为:
unsigned int y = 0x80000000;那么这种缓冲区溢出错误将不会发生。
unsigned int x; unsigned int y; unsigned int result; /*初始x,y,result*/ if(y>=sizeof(unsigned int) * CHAR_BIT) { // 错误处理 } else { result=x>>y; }这里还需要说明的是,对于变量 x 与 y,C99 规定:
unsigned int x=10; x+=(x<<3)-5;虽然上面的代码是一条合法的优化语句,但是它的确严重地破坏了程序的可读性。因此,建议采用下面的方式来书写代码:
unsigned int x=10; x=x*9-5;或许这时候有读者会问,这样写代码不就降低了程序的执行效率吗?
unsigned int x=8; unsigned int y=x*4; unsigned int z=x/2;上面的代码在 Microsoft Visual Studio 2010 集成开发环境 VC++ 的 Debug 模式下将生成如下汇编代码:
unsigned int x=8; 00DB139E mov dword ptr [x],8 unsigned int y=x*4; 00DB13A5 mov eax,dword ptr [x] 00DB13A8 shl eax,2 00DB13AB mov dword ptr [y],eax unsigned int z=x/2; 00DB13AE mov eax,dword ptr [x] 00DB13B1 shr eax,1 00DB13B3 mov dword ptr [z],eax从上面的汇编代码可以看出,编译器会自动在汇编代码中用移位操作来优化乘除法运算。因此,完全没有必要用手工进行这种优化,编译器会自动完成。我们应该把精力放在改进程序的算法上,一个好的算法可以使程序运行效率大大提高。当然,如果除数为 2 的幂,那么在进行除法运算时可以适当地采用移位算法来实现乘除法。
#include <stdio.h> int main (void) { int x=-2147483647; x=x<<1; printf("%d \n",x); return 0; }在上面的代码中就要注意精度问题,在 32 位系统中,int 类型占 4 个字节,精度范围为“-2147483647~2147483647”。其中,数据“-2147483647”的原码为“11111111111111111111111111111111”,补码为“10000000000000000000000000000001”。现在将“10000000000000000000000000000001”左移 1 位,最高位的1没有了,最低位左移一位,得到的结果为 2。
本文链接:http://task.lmcjl.com/news/12565.html