关于指针
1 #include <iostream> 2 using namespace std; 3 4 struct Test 5 { 6 int Num; 7 char *pcName; 8 short sDate; 9 char ch[2]; 10 short str[4]; 11 }*p; 12 13 void main() 14 { 15 p = (Test*)0x100000; 16 17 printf("p+0x01 -> 0x%08x\n", p+0x01); 18 printf("(unsigned long)p+0x01 -> 0x%08x\n", (unsigned long)p+0x01); 19 printf("(unsigned int*)p+0x01 -> 0x%08x\n", (unsigned int*)p+0x01); 20 }
这个题主要考查指针,算的上经典。
struct Test结构体的大小是20byte(十六进制0x14)
所以
p+0x01,此时p还是Test *类型,故根据指针运算规则,p+0x1,p的值实际上是往后移Test *的大小,即0x100000+0x14 = 0x100014
(unsigned long)p+0x01,这里先将p强制类型转换为unsigned long型,则加法运算将其当作一个数来运算,所以为普通的加法,结果自然为0x100000+1 = 0x100001
(unsigned int*)p+0x01,这里先将p强制类型转换为unsigned int*型,即转换为一个unsigned int*的指针,unsigned int占4个字节的大小,则p+0x01往后移4个字节,即0x100000+0x4 = 0x100004
这里实际上要理解,在32位机上,指针本身始终只占用4个字节的空间,指针的类型只不过是给编译器解释它的值的时候使用的,什么类型的指针,编译器就知道指针的值所表示的是一个什么结构的数据。
这也是为什么在函数传参时使用指针高效的原因,因为始终只占4个大小的空间,而在函数中可以依据指针的类型将值取出来。
而传值时是拷贝操作,如果一个结构体很大,会很低效。
这些行为都跟编译器有关。