C 语言中的左移和右移运算
C 语言中的左移和右移运算 (>> 和 <
1、各种数据格式(整型int ,字符型 char 等)占有几个存储单元(不同的编译器有所不同)
在TC2.0和keil中:(也是ANSI的标准)
char占有1个字节(即8位二进制数)。unsigned char类型的变量,最大值为Oxff (十
六进制), 255 (十进制)
int占有2个字节(即16位二进制数)。unsigned int类型的变量,最大值为Oxffff (十六
进制), 65535 (十进制)
long int 占有 4 个字节
folat 占有 4个字节, long float 和 double 都占有 8个字节, long double 占 16 个字节
在VC++中:
char 占有 1 个字节, int 和 float 占有 4 个字节, double 占有 8 个字节
2、逻辑左移 /右移和算术左移 / 右移的区别(这两种位运算,仅适用于整型和字符型。对实数型 格式的数据不适用)
逻辑左移:丢弃最低位,移 1 位,得: 0111 11110 补最高位。 (假设仅左移1
逻辑左移:丢弃最低位,
移 1 位,得: 0111 1111
0 补最高位。 (假设仅左移
1 位)二进制数:
1111 1111 逻辑左
逻辑右移:丢弃最高位,
移 1 位,得: 1111 1110
0 补最低位。 (假设仅右移
1 位)二进制数:
1111 1111 逻辑左
算术左移:以保持符号位不变为基础,进行逻辑左移1000 1111
算术左移:以保持符号位不变为基础,进行逻辑左移
1000 1111 得: 1100 0111
假设仅左移 1 位)二进制数:
算术右移:以保持符号位不变为基础,进行逻辑右移假设仅右移
算术右移:以保持符号位不变为基础,进行逻辑右移
假设仅右移 1 位)二进制数:
1000 1111 得: 1001 1110
好了,进入正题: (分无符型和有符型进行讨论)
以下结果,是通过 VC++6.0 调试的( char 占 1 字节, int 占 4 字节)
需要注意的一点是: 计算里的运算都是通过二进制补码进行的, 所以在对两个操作数进行运算时, 要先将它们转化成补码形式。
1、无符型情况unsigned char 和 unsigned int
(以 unsigned char 型为例, unsigned int 型情况相同)
>> 右移
unsigned char i=0x99;// 二进制数补码形式为: 1001 1001
i=i>>1;
printf("ni=0x%xn",i);//%x 是指,运行的结果以十六进制的形式显示
程序运行结果:
i=0x4c;即卩 0100 1100
<< 左移
i=0x99;
i=<<1;
程序运行结果:
i=0x32;即 0011 0010
2、有符型char 和 int
左移 <<
char i= - 9;//i 的二进制原码: 1000 1001 补码: 1111 0111
char y=-0x49;i=i<<1;//y 的二进制原码: 1100 1001 补码: 1011 0111
char y=-0x49;
i=i<<1;
// 经逻辑左移后, i 的补码: 1110 1110 (是个
j=j<<1;(十进制)// 经逻辑左移后,j 的补码 :0001 0011 (是个正数,原码和补码一样)即18x=x<<1;// 经逻辑左移后,
j=j<<1;
(十进制)
// 经逻辑左移后,
j 的补码 :0001 0011 (是个正数,原码和补码一样)即
18
x=x<<1;
// 经逻辑左移后,
x 的补码 :1001 0010 (是个负数,需再求其补) ,得原码:
1110 1110 即 -110 (十进制)
y=y<<1; // 经逻辑左移后, y 的不码 :0110 1110 (是个正数,原码和补码一样)即 110 (十进制)
printf("i=%dnj=%dnx=%dn",i,j,x);
程序运行结果:
i= - 18;
j=18;
x= - 110;
y=110;
在 C 语言中, VC++6.0 环境下:
对一个数进行位移操作,就是对它的补码进行逻辑位移操作
如果这个数是无符型,则逻辑操作的结果就是它的最终位运算结果;
如果这个数是有符型, 则还需对个逻辑操作的结果进行一次取补, 取补后的结果方为最终运算结 果。
补充说明:
1、如果位移动的数目大于