1.写出下列程序的输出结果:
int main()
{
int arr[5]={1,2,3,4,5};
int *ptr=(int*)(&arr+1);//取出数组arr的地址,加1表示跳过整个数组,ptr指向的是5后面的地址
printf("%d %d\n",*(arr+1),*(ptr-1));
//*(arr+1)表示取出数组arr的首地址,加1表示指向第二个元素
return 0;
}
2.写出下列程序的输出结果:
int main()
{
int arr[4]={1,2,3,4};
int *ptr1=(int *)(&arr+1);
int *ptr2=(int *)((int)arr+1);//arr为数组首元素地址,强制类型转换为int,加1表示加4个字节
printf("%x,%x",ptr1[-1],*ptr2);//ptr1[-1]=*ptr1+(-1),向前移动四个字节
}
ptr1[-1]的十六进制输出是4;*ptr2的十六进制输出是2000000。
3.下面代码输出什么?
int main()
{
int a[5][5];
int (*p)[4];//数组指针(定义了p[0],p[1],p[2],p[3]四个指针,本质还是数组)
p=a;//从同一地址处开始
printf("%d\n",&p[4][2]-&a[4][2]);
return 0;
}
由图知&p[4][2]和&a[4][2]差四。
4.下面代码输出结果是什么?
#include <stdio.h>
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
int main()
{
p = 0x100000;
printf("%p\n", p + 0x1); //p是一个指向结构体的指针,加1就意味着跳过整个结构体
printf("%p\n", (unsigned long)p + 0x1); //p强制类型转化为无符号长整型,加1直接加
printf("%p\n", (unsigned int*)p + 0x1); //p指向无符号整型的指针,加一跳过四个字节
return 0;
}
结构体Test的大小为20.
p + 0x1=0x100014;
(unsigned long)p + 0x1=0x100001;
(unsigned int*)p + 0x1)=0x100004.
5.这道题比较复杂,逻辑性较强。
int main()
{
char*c[]={"ENTER","NEW","POINT","FIRST"};//指针数组
char** cp[] = { c + 3, c + 2, c + 1, c };
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *--*++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);
return 0;
}
将本题题干进行画图总结:
接下来一句一句画图就不会迷路喽!!
**++cpp
cpp原先指向的是cp的第一个元素c+3,++cpp指向cp的第二个元素c+2,解引用得到cp第二个元素,再解引用得到cp的第二个元素指向的内容–POINT
*--*++cpp + 3
上一句的++cpp的作用延续到这句,所以这次++cpp指向的是cp的第三个元素c+1,解引用得到c+1的内容,然后进行自减,解引用之后得到c的第一个元素–ENTER,加3之后指向E(第二个),输出–ER.
*cpp[-2] + 3
*cpp[-2] + 3 = **(cpp+(-2))+3
上述自增效果延续,cpp+(-2)指向cp的c+3,双重解引用之后得到FIRST,加3之后输出–ST.
cpp[-1][-1] + 1
cpp[1][-1] + 1 =*(*(cpp-1)-1) + 1
第三句没有cpp的自增自减,所以延续的是第二句的cpp的位置,*(cpp-1)
之后指向cp的c+2,再减一就指向c的c+1,加3指向E,输出EW.