移位操作分为左移位<<和右移位>>两种,C规定若移位的右操作数为负数或大于等于左操作数的位宽(int为32位,char为8位)时,其行为未定义。
1.符号类型的左移位
左移位操作,空位部分填充零。如下图:
错误代码:
-
int si1, si2, sresult;
-
sresult = si1 << si2
若si2为负数或大于等于sizeof(int)*CHAR_BIT时,行为未定义。
正确:
-
int si1, si2, sresult;
-
if ( (si1 < 0) || (si2 < 0) || (si2 >= sizeof(int)*CHAR_BIT) || si1 > (INT_MAX >> si2) ) {
-
/* handle error condition */
-
}
-
else {
-
sresult = si1 << si2;
-
}
2.无符号类型的左移位:空位部分填充零。
错误:
-
unsigned int ui1, ui2, uresult;
-
uresult = ui1 << ui2
当ui2大于等于sizeof(int)*CHAR_BIT,行为未定义。
正确:
-
unsigned int ui1, ui2, uresult;
-
if ( (ui2 >= sizeof(unsigned int)*CHAR_BIT) || (ui1 > (UINT_MAX >> ui2))) ) {
-
/* handle error condition */
-
}
-
else {
-
uresult = ui1 << ui2;
-
}
3.右移位操作
列如,E1>>E2,若E1为有符号类型且为负值,则其行为是implementation-defined,其实现由编译器决定,可以是算术右移位或逻辑右移位。
算术右移操作:移出的空白位用符号位填充。下图符号位为1,空白就用1填充。
逻辑右移位:就是空白位用0填充。
错误代码:
-
int si1, si2, sresult;
-
unsigned int ui1, ui2, uresult;
-
sresult = si1 >> si2;
-
uresult = ui1 >> ui2
对si2或ui2没有做判断。
正确:
-
int si1, si2, sresult;
-
unsigned int ui1, ui2, result;
-
if ( (si2 < 0) || (si2 >= sizeof(int)*CHAR_BIT) ) {
-
/* handle error condition */
-
}
-
else {
-
sresult = si1 >> si2;
-
}
-
if (ui2 >= sizeof(unsigned int)*CHAR_BIT) {
-
/* handle error condition */
-
}
-
else {
-
uresult = ui1 >> ui2;
-
}
阅读(1179) | 评论(0) | 转发(0) |