char a = 64;
char b = 64;
a*=2;
b<<=2;
printf("%d %d",a,b); //-128 -128
a/=2;
b>>=2;
printf("%d %d",a,b);//-64 -64
逻辑移位不考虑符号位,算术移位考虑符号位。
c/c++中有符号数的右移都是算术移位,左移是逻辑移位。
unsingned和signed比较的话,会转成无符号比较。
a = -3, a/2 是-1, a>>1是 -2。
个人一直不太习惯于unsigned int/char,可能因为嫌打字麻烦(得多打个unsigned),同时unsigned int实际上也没看到有很大的必要。只不过作为一种代码风格保证其值非负而已。然而多数人确实也不大愿意用unsigned:
vector<Type> v;
for(int i = 0; i < v.size(); ++i)
在以上例子上使用int 而不是unsigned几乎是普遍的事实了,虽然unsigned或许可以更让人从信念上产生对i非负的一种信心。然而如果使用不当,unsigned可能会产生让你困惑的事情:
vector<Type> v;
for(unsigned i = 0; i < v.size() - 1; ++i)
在此种情况下,假如v为空,那么unsigned(0)-1将是个0xffffffff,一个大整数,这其实可能并不是你所期望的。。。当然,如果把代码风格换为如下的,可以避免此问题发生(对于unsigned来说+比-更给人安全感
):
![](http://blog.csdn.net/Editor/FCKeditor/editor/images/smiley/msn/regular_smile.gif)
vector<Type> v;
for(unsigned i = 0; i+1 < v.size(); ++i)
由于个人的偷懒,所以我经常尽量避免用unsigned,今天终于尝到了恶果。。。
void encrypt(const char* src, int length, const char** dest) //简单加密
{
*dest = new char[length];
for(int i = 0; i < length; ++i)
(*dest)[i] =sr[i]<<4 | sr[i]>>4; //高4位和低4位呼唤,通过移位来实现
}
void decrypt(const char* src, int length, const char** dest) //简单解密
{
encrypt(src, length, dest);
}
然而我发现对于一些数据简单加密后简单解密结果是对的,但是部分数据结果是错误的。后来分析了下发现是移位运算符的原因。当作用于右移移位运算符>>的数是signed & negative时,由于其算术移位(而非逻辑移位)的特性,
负号将被继续扩展到适当位中。。。 总结下,即:signed int/char 对应于算法移位,unsigned int/char对应于逻辑
移位!以下unsigned版本结果正常:
void encrypt(const unsigned char* src, int length, const unsigned char** dest) //简单加密
{
*dest = new unsigned char[length];
for(int i = 0; i < length; ++i)
(*dest)[i] =sr[i]<<4 | sr[i]>>4; //高4位和低4位呼唤,通过移位来实现
}
void decrypt(const unsigned char* src, int length, const unsigned char** dest) //简单解密
{
encrypt(src, length, dest);
}
经过上述的例子之后,个人的感觉是:在合适的地方用unsigned,不要偷懒,那样也会使你的代码容易更清晰。