user-0 提问: 一个关于位运算的宏定义求解（百分悬赏）！！

回复:
user: user-1
content: http://bbs.csdn.net/topics/390150105

user: user-2
content: 。。这个运算怎么逆过来啊。楼主做了吗

user: user-3
content: 顶，只为赚分

user: user-4
content: GETLONG就是从data指向的地址取4个字节，组成一个32位的unsigned long  #define MCGETCHAR(data)  (*((char *)(data))) #define MCGETSHORT(data) \         ((unsigned short)(( ((unsigned short)(*((char *)(data))))<<8 )|( ((unsigned short)(*((char *)(data)+1)))&0x00ff ))) #define MCGETLONG(data) \         ( ( ((unsigned long)MCGETSHORT((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+2))&0x0000ffff ) ) #define MCGET3BN(data)  \         ( ( ((unsigned long)MCGETCHAR((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+1))&0x0000ffff ) )  #include <stdio.h>  int main(int argc, char *argv[]) {         char buf[4] = {0x12, 0x34, 0x56, 0x78};         unsigned char  uc;         unsigned short us;         unsigned long  ul;          unsigned long  u3;          /* 取一个字节 */         uc = MCGETCHAR(buf);         /* 取两个字节，组成short */         us = MCGETSHORT(buf);         /* 取四个字节，组成long */         ul = MCGETLONG(buf);         /* 取3个字节， 作为long的低24位, 高8位是零 */         u3 = MCGET3BN(buf);          printf("0x%02x 0x%04x 0x%08x 0x%08x\n", uc, us, ul, u3);          return 0; }  /* 输出:  0x12 0x1234 0x12345678 0x00123456  */

user: user-5
content: 就是将高地址和低地址上的值互换

user: user-6
content: 看着有中想跪的感觉

user: user-7

user: user-0
content: 引用 24 楼 Idle_ 的回复:不就是大小端互换吗？知道啦，谢啦谢啦~~~

user: user-0
content: 引用 23 楼 zilaishuichina 的回复:[quote=引用 21 楼 zilaishuichina 的回复:] 应该是 第2字节在最高位 第1字节在次高位 第4字节在次低位 第3字节在最低位  错了 还是 低地址的数据在高位，高地址的数据在低位  比如  int a = 0x12345678 int b=MCGETLONG(&a) //b = 0x78563412[/quote]搜噶····

user: user-8
content: 不就是大小端互换吗？

user: user-9
content: 引用 21 楼 zilaishuichina 的回复:应该是 第2字节在最高位 第1字节在次高位 第4字节在次低位 第3字节在最低位  错了 还是 低地址的数据在高位，高地址的数据在低位  比如  int a = 0x12345678 int b=MCGETLONG(&a) //b = 0x78563412

user: user-10

user: user-9
content: 应该是 第2字节在最高位 第1字节在次高位 第4字节在次低位 第3字节在最低位

user: user-9
content: #define MCGETSHORT(data)													\ (																			\ 	(unsigned short)(														\ 						(													\ 							(												\ 								(unsigned short)(							\ 													*(						\ 														(char *)(data)		\ 													)						\ 												)							\ 							) << 8											\ 						)													\ 																			\ 						|													\ 																			\ 						(													\ 							(												\ 								(unsigned short)(							\ 													*(						\ 														(char *)(data) +1	\ 													)						\ 												)							\ 							) & 0x00ff										\ 						)													\ 					)														\ )  //data值所代表的那个地址，比如data为0x1b2ec， //(char *)(data)就是内存地址0x1b2ec //*((char *)(data))就是内存地址0x1b2ec里面的值X //(unsigned short)(*((char *)(data)))从地址0x1b2ec取一个char数据然后强转为short数据Y1 //Y1右移八位，就是比如Y1是0x12，变成0x1200  //下面类似 //(char *)(data) + 1 就是内存地址0x1b2ed //(unsigned short)(*((char *)(data)))从地址0x1b2ed取一个char数据然后强转为short数据Y2 //Y2 & 0x00ff，就是比如Y2是0x34，变成0x0034  //Y1 | Y2 就是 0x1200 | 0x0034 = 0x1234  //(unsigned short)(Y1 | Y2) 强转为short  //MCGETLONG类似  a=1b2ec // 这个应该是0x1b2ec  b=MCGETLONG(a) 取得地址为0x1b2ec里面4个字节的数据  低地址的数据在高位，高地址的数据在低位

user: user-11
content: 引用 14 楼 liyachen777 的回复:[quote=引用 11 楼 lovesmiles 的回复:] 你写漏东西了  //声明宏函数 #define MCGETCHAR(data)  (*((char *)(data))) #define MCGETSHORT(data)  ((unsigned short)(( ((unsigned short)(*((char *)(data))))<<8 )|( ((unsigned short)(*((char *)(data)+1)))&0x00ff ))) //这是对short的处理，就是两个字节，将低字节复制到高位 #define MCGETLONG(data)  ( ( ((unsigned long)MCGETSHORT((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+2))&0x0000ffff ) )//这是对long的处理，就是四个字节，将低两字节复制到高位两字节  MCGETLONG展开后的结果就是四个字节的值都用低位字节的值表示。。··········额，那如果给了一个超出四位的数呢·····[/quote] unsgined long的长度就是4个字节，怎么超？超过了就当它只有4个字节，高位的全部看不见。

user: user-11
content: 引用 16 楼 liyachen777 的回复:引用 5 楼 zilaishuichina 的回复:求 MCGETSHORT下面有，求解啊，大神！ 给个直观的例子你: 例如 data = 0xabcd; data1 = MCGETLONG(data); data1 就是0xdddd  就是将最低位的d复制到这四字节。

user: user-12
content: 引用 12 楼 liyachen777 的回复:大神，那要是出个十六进制数，是不是先转成二进制，然后右移16位，然后跟后面那个比较？？？额···还是晕了，能通俗一点么···· 内存中的所有数据都是2进制，如果人要看的话可以转换成十六进制给人看 右移十六位是数学运算，即乘以2的16次方，和内存大小端没有关系 要容易理解，你可以把这个宏写成函数，每一个小运算都单独列一行，然后理解起来就容易得多，也可以一边调试一边观察 像这种有点复杂的运算，其实建议写成内联函数，比写成宏好得多

user: user-0
content: 引用 5 楼 zilaishuichina 的回复:求 MCGETSHORT下面有，求解啊，大神！

user: user-0
content: 引用 13 楼 lovesmiles 的回复:抄个代码也不会看啊，我把你的源码在网上找到了 int read(char acFilePath[]) {  int nsizecount = 2 ;     //结构体数组从第二个位置开始存储数据 ；  FILE* pfp ;              //指针指向二进制文件 ；    char actotalsize[2] ;    //从二进制文件中读取道路信息的总体数据长度 ；  char aclinkId[4] ;       //从二进制文件中读取道路编号 ；  char acroadnamesize[2] ; //从二进制文件中读取道路名称数据长度；  char acNodeInfo[4] ;     //存储从二进制文件中读取的值 ；  pfp = FileOpen( acFilePath ) ;                           //读取文件： 打开原始文件或用户手动输入的文件路径名称 ；   start=clock();  printf("\n\t   读取文件.") ;     printf("\n\t   读取中......") ;        while( 1 )                 //循环读取数据，直到pfp指针指向文件的末尾 ；  {       if( fread( actotalsize , sizeof(actotalsize) , 1 , pfp ) == NULL )   {        fclose(pfp) ;       end=clock();       printf("\n\t   文件读取成功，用时%f秒\n\n",(double)(end-start)/CLOCKS_PER_SEC);       return nsizecount-1 ;   }        fread( aclinkId , sizeof(aclinkId) , 1 , pfp ) ;         //读取占用4字节的linkId字符串；      fread( acroadnamesize , sizeof(acroadnamesize) , 1 , pfp ) ;                              //读取占用2字节的roadnamesize字符串；      fread( acNodeInfo , sizeof(acNodeInfo) , 1 , pfp ) ;                                    //读取占用4 字节的dispclass ， brunch ， 和 roadnameflag字符串 ；                             //调用宏函数 ， 将字符串信息转化为数值类型  ；         unsigned short ustotalsize = MCGETSHORT( actotalsize ) ;         unsigned long  ullinkId = MCGETLONG( aclinkId ) ;         unsigned short usroadnamesize = MCGETSHORT( acroadnamesize ) ;                               //赋值 ：将数值信息传到结构体中  ；         road[nsizecount].ussize = ustotalsize ;         road[nsizecount].ullinkId = ullinkId ;         road[nsizecount].usroadnamesize= usroadnamesize ;                              //从一个字节中读取dispclass ， brunch 以及roadnameflag的值 ；      int m=(int)acNodeInfo[3]&255;      road[nsizecount].usdispclass=m&15;      road[nsizecount].usbrunch=(m&112)/16;      road[nsizecount].usroadnameflag=(m&128)/128;                           //从文件中读取道路名称 ；      fread( &road[nsizecount].roadname , sizeof(char) , ustotalsize - 12 , pfp ) ;            nsizecount++;  }      return 0; }额······那我的四句宏定义是不是就是这个功能·····

user: user-0
content: 引用 11 楼 lovesmiles 的回复:你写漏东西了  //声明宏函数 #define MCGETCHAR(data)  (*((char *)(data))) #define MCGETSHORT(data)  ((unsigned short)(( ((unsigned short)(*((char *)(data))))<<8 )|( ((unsigned short)(*((char *)(data)+1)))&0x00ff ))) //这是对short的处理，就是两个字节，将低字节复制到高位 #define MCGETLONG(data)  ( ( ((unsigned long)MCGETSHORT((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+2))&0x0000ffff ) )//这是对long的处理，就是四个字节，将低两字节复制到高位两字节  MCGETLONG展开后的结果就是四个字节的值都用低位字节的值表示。。··········额，那如果给了一个超出四位的数呢·····