学过C的大都认为,指针是一个让人极其头疼的点;今天,就由我带大家领略几道指针的面试题。
int main()
{
int a[5] = {
1,2,3,4,5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
输出结果:2,5
struct Test {
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;//创建了一个结构体指针,类型为struct Test{ }*,变量名为p
//已知,struct Test类型的变量大小为20字节
int main()
{
p=(struct Test*)0x100000;//假设p的值为0x100000
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
输出结果为:00100014 、 00100001 、00100004
分析:p是结构体类型指针,存放的地址为0x00100000,这个地址加上十六进制数0x1(十进制的1);因为struct Test类型的结构体大小为20字节,所以这里指针p的步长为20,因此p+0x1得到00100014; (unsigned long)p把0x00100000转换为无符号整型,也就是十进制的1048576,加上0x1后变成1048577,再以%p的形式打印,得到0x00100001; (unsigned int*)p把0x00100000转换为无符号整型指针类型,p的步长变成4,加上0x1后变成0x00100004;
(这里看不懂的可以看看这篇文章哦)
int main()
{
int a[4] = {
1,2,3,4 };
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (int*)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
输出结果: 4 , 2000000
分析:由于计算机的小端存储模式,数组a在内存中的存放方式为:
ptr1[-1]等价于*(ptr-1),由于是int类型,所以内存访问权限为4个字节,所以从指针ptr[-1]处访问四个字节,也就是04 00 00 00,由于是小端存储模式,所以实际上的数据为00 00 00 04,所以以%x(十六进制)输出得到 0x4;
a是首元素地址,设为0x00000001,将其强制类型转化为int型,得到十进制数1,加1后得到十进制数2,然后将 2强制类型转化为int类型,得到整型指针0x00000002,所以int*ptr2=0x00000002,其解引用访问四个字节,也就是00 00 00 02,最后以%x输出得到0x02000000;
注:内存中每一个字节都有一个地址,所以地址+1就是向后偏移一个字节
int main()
{
int a[3][2] = {
(0,1) ,(2,3), (4,5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}
输出结果为:1
分析:数组初始化里有逗号表达式,其结果是最后一个表达式的结果,所以实际上初始化的内容为{1,3,5,0,0,0};指针p里存放的a[0]是数组第一行的地址,也是第一行首元素的地址,p[0]等价于*(p+0),也就是对首元素地址进行解引用
然后以%d打印,得到首元素1;
关于指针的题分为两期讲解哦,欢迎关注~~
不知我有没有讲清楚呢?有什么问题欢迎下方留言哦。
//创作不易,点赞评论再走呗by白龙码