signed unsigned

来源:互联网 发布:寂静如歌 李健 知乎 编辑:程序博客网 时间:2024/04/29 03:33

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来说+比-更给人安全感):
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,不要偷懒,那样也会使你的代码容易更清晰。
原创粉丝点击