求助:问一个别人代码中看到的关于<<运算符的问题,实在想不明白
截取下来关键的一些代码,如下:
#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的数据结构很多的。