写出下列程序的结果。
1.
#include<stdio.h> int main () { int a[5] = { 1,2,3,4,5 }; int* par = (int*)(&a + 1); printf("%d %d", *(a + 1), *(par - 1)); }
结果:
解析:
(1)int * par = (int*) (&a + 1) —— &a,取出整个数组的地址,再 + 1 ,跳过20个字节(整个数组),然后将其强制转换为整型类型,存入整型指针par中,par 指向数组的后面。
(2)* (a+1) —— a是数组名,代表首元素地址,+1,跳过4个字节,即a+1相当于&a[1],所以打印结果为2。
(3)* ( par-1 ) —— par指向数组a后面的地址,par是整型指针,- 1,指针往后移4个字节,所以指针指向的是a[4]的地址,所以打印结果为5。
2.
#include<stdio.h> struct test { int num; char* name; short date; char ch[10]; }*p;//结构体大小为20 int main() { p = (struct test*)0x00100000; printf("%p\n",p+0x1); printf("%p\n", (struct test*)((unsigned long)p+0x1)); printf("%p\n", (unsigned int*)p + 0x1); }
结果:
解析:
(1)p = ( struct test * ) 0x00100000 ,p是一个结构体指针 ,0x100000是一串十六进制数,通过类型强制转换,将它变为结构体类型的地址,存在指针p中。
(2)题中出现的0x1,是十六进制数,等于十进制数1。
(3)printf (" %p\n " , p + 0x1 ) —— p + 0x1就等于p+1 ,p是结构体类型指针,+ 1 ,指针后移20个字节,地址是用十六进制表示,所以相当于地址加0x14,故打印结果为 0x00100014。
(4)printf (" %p\n ", ( struct test* ) ( ( unsigned long ) p + 0x1 ) ) —— ( unsigned long ) p,将p转换为无符号长整形数 100000,+ 1,变成100001,再将其转换结构体类型的指针,所以打印结果为00100001。
(5)printf(" %p\n " , ( unsigned int * ) p + 0x1 ) —— ( unsigned int * ) p,将p转换为无符号整型指针,+ 1 ,指针后移4个字节,所以打印结果为00100004。
3.
#include<stdio.h> int main() { int a[4] = { 1,2,3,4 }; int* par1 = (int*)(&a + 1); int* par2 = (int*)((int)a + 1); printf("%x %x", par1[-1],*par2); }
结果:
解析:
1,2题中与这道题重复考点不再讲解。
这个结果是在vs上的编译结果,采用的是小端存储模式。
小端存储模式:数据的高位保存在高地址处。
比如1的储存:
这道题中:
*par的打印结果位2000000