今天做老师布置的作业Take Assessment: Exercise 1: Decoding Lab(实验分析)时,遇见一串代码:
int dummy = 1; //...省略若干代码段 start = (int)(*(((char*)&dummy))); stride = (int)(*(((char*)&dummy) + 1));
而start值为1,stride值为0。
被(int)(*(((char*)&dummy)))这一大串搞迷糊了,网上查解释也没理解。
大概明白&dummy是指存放dummy数据的地址,可为啥要转换为char*型指针所指,又转换回int?作用何在?为何start等于1、stride又等于0了呢?
后来捣鼓一番有所领悟,故做此笔记:
一、
首先,我们要明白,不同类型的数据,在内存中存放在连续的存储单元中,占用不同的字节长度。在C/C++中,int型占4个字节,char型占1个字节。每个字节8位。故一个int型数据,是用32位的二进制数表示;一个char型数据,是用8位的二进制数表示。
int main() {
cout <<"size of int in C/C++:" << sizeof(int) << endl;
cout << "size of char in C/C++:" << sizeof(char) << endl;
return 0;
}
该段代码输出:
size of int in C/C++:4 size of char in C/C++:1
二、
然后来正式讲解(int)(*(((char*)&a)))的含义。看看以下例子:
int main() {
int dummy = 612;
int a = (int)(*(((char*)&dummy)));
int b = (int)(*(((char*)&dummy) + 1));
cout << "a=" << a << endl;
cout << "b=" << b << endl;
return 0;
}
毫无疑问,dummy的取值会影响a和b的计算结果。而dummy=1时,a=1,b=0,他们之间的关系很不直观。所以我们把dummy值设大一点,为612。
612(十进制) = 10,01100100(二进制)
612这个数换算成二进制有10位,最低八位为01100100,最高二位为10。
现在我们运行代码,得到结果:
a=100 b=2
这有什么含义呢?把100和2用二进制表示,结果一目了然:
100(十进制) =1100100(二进制)——一共7位,把它补全8位为01100100
2(十进制) = 10(二进制)
分别对应612的二进制数的低八位和高二位。
所以可以得出结论:(int)(*(((char*)&a)))是整数a的二进制表示的最低八位所对应的十进制数,(int)(*(((char*)&a+1)))是整数a的二进制表示的9~16位二进制所对应的十进制数。
也即:
把612换算成二进制数->截取其最低8位(01100100)或9~16位(00000010)的二进制数->将截取的二进制数转换为十进制(100或2)
三、
简单阐述转换的具体细节:
- 代码第一行,初始化一个int型数据dummy,内存中开辟4个字节(32位)的空间给其存放:
- &dummy是dummy在内存中存储的首个字节的地址。
- (char*)&dummy,相当于搞了一个char*型指针,指向&dummy这个首地址。此时的&dummy,可以理解为“存放了某个字符(该字符对应的二进制表示为01100100)”的字符空间单元。
- ((char*)&dummy) + 1,是让char*指针移向下一个字符单元。而由于char在C/C++中只占一个字节,所以指针只会向下移一个字节,也即指向了00000010存放的地址。
- *(((char*)&dummy + 1)),其中里面的这一段((char*)&dummy + 1)其实就是个char指针,而*指针表示的是指针所指地址的内容。比如00000010所对应的字符。
- (int)(*(((char*)&dummy) + 1)),把一个字符显式转换成int型。字符对应的二进制数是00000010,那么转换成的int型的二进制表示也是00000010,换成十进制就是2。
四、
现在应该明白这一行绕弯的代码所表示含义了,明白不同的dummy输入该输出什么值。
int main() {
int dummy = 2147483647;
int a = (int)(*(((char*)&dummy)));
int b = (int)(*(((char*)&dummy) + 1));
int c = (int)(*(((char*)&dummy) + 2));
int d = (int)(*(((char*)&dummy) + 3));
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
return 0;
}
这段程序该输出
-1 -1 -1 127
因为2147483647的二进制对应的是低31位都是1,最高位32位为0嘛。-1对应的二进制存储形式是11111111,127对应的存储形式是01111111。
还可以把char改为short int类型的指针,由于short int占两个字节,那么每次执行((short int*)&dummy) + 1,就是跳两个字节地址了;(int)(*(((short int*)&dummy) + 1))的数值范围,也从-127~127(2^7-1)变为-32767~32 767(2^15-1)了。
int main() {
int dummy = 612;
int a = (int)(*(((short int*)&dummy)));
int b = (int)(*(((short int*)&dummy) + 1));
cout << a << endl;
cout << b << endl;
return 0;
}
输出:
612 0



