首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

:问一个别人代码中看到的关于<<运算符的有关问题,实在想不明白

2012-02-21 
求助:问一个别人代码中看到的关于运算符的问题,实在想不明白截取下来关键的一些代码,如下:#includestda

求助:问一个别人代码中看到的关于<<运算符的问题,实在想不明白
截取下来关键的一些代码,如下:
#include   "stdafx.h "

#define   A(c1,c2,c3,c4)   (c1 < <24   |   c2 < <16   |   c3 < <8   |   c4)

int   _tmain(int   argc,   _TCHAR*   argv[])
{
char   b[4]   =   { 'a ', 'b ', 'c ', 'd '};
unsigned   long   *a   =   new(unsigned   long   );
*a   =   A( 'a ', 'b ', 'c ', 'd ');

                    return   0;
}
在return   0;这里设置断点,调试,a所指向的内存地址的连续的4个字节是64,63,62,61
(big   endian的缘故).看不懂这里的操作(c1 < <24   |   c2 < <16   |   c3 < <8   |   c4),c1不是只是一个8位的变量吗,把它左移应该还是8位的变量,照我的理解应该是c1左移24位得到的8位变量和c2左移16位得到的8位变量和c3左移8位得到的8位变量和c4这个8位变量相或,应该还是一个8位变量.为什么不是这样呢?应该怎么样理解?谢谢啦先:)

[解决办法]
可以用下面的结构和代码解释:

union Byte_Long
{
unsigned long value;
struct
{
char c4;
char c3;
char c2;
char c1;
};
};


Byte_Long v;
v.c1 = 'a ';
v.c2 = 'b ';
v.c3 = 'c ';
v.c4 = 'd ';
[解决办法]
虽然kuanghanli(度)兄写的不是很清楚,但我想我跟你理解的应该查不多
我说下我的想法:
不管你当初定义的变量是多少位的,在进行移位操作时(实际上任何操作都是如此),实际上都是在对一个32位数(假定机器是32位的)进行操作。
这是为什么呢?因为你的机器本来就是32位的!当CPU从内存里面取出一个8位的char放到寄存器里面的时候,寄存器里的数据当然是32位而不是8位,当CPU真正进行移位操作的时候,它处理的当然还是一个32位数而不是一个8位数!
最后的赋值实际上包含一个截断的过程:如果左边是一个8位变量,那就把32位的操作结果截低8位给它;如果左边是一个16位变量,那就把32位的操作结果截低16位给它;如果左边是32位,直接赋值就OK了!
[解决办法]
to mayiding()

有一点是可以肯定的,我在写代码时,正如你所说,是假定机器是32位的,而目前的事实是,好像还没发现64位编译器,因此,我的代码在目前的32位编译器编译的代码应该是正确的,如果非要考虑代码兼容性的问题,我的代码就不那么正确了:如果用64位编译器,必须初始化v.value,如果用16位编译器,则完全是错误的,所以代码正确与否,到不是取决于多少位的CPU或者寄存器,而是与编译器有关。这一点大家都知道,而且我只是随手写的几行代码,想向楼主说明移位赋值后的结果,用不着kuanghanli(度)大惊小怪,如果他直接说代码可能以后存在移植性问题,我完全同意,但是他说话的语气显然是在卖弄什么,我想了一会,才明白原来是指责我的代码错误!说实在话,我还用不着他来说什么,一看就是个半罐子!
其实,真到了32位代码向64位移植时,好多系统都得修改,你去看一些库的源代码,象我的这种假定32位long的数据结构很多的。

热点排行