前言
今天分享几道这个关于指针运算的笔试题,希望能够帮助到各位老板。那么接下来,就让我们一起看看~
练习题
练习题1
代码如下:
#include <stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
//程序的结果是什么?
运行结果:
分析:
- 首先,我们通过画图来解析:
- 我们看到,这是一个数组,元素类型都是int。然后,int* ptr = (int*)(&a + 1); &a是数组的地址和数组首元素的地址是一样的,是在上图的红色&a,对它进行+1,就到了图中红色的 &a+1 , 这涉及到了指针的+ - ,对它进行强转为(int*)赋值给指针变量ptr。
- ptr指向的位置和&a+1是一样的,最后ptr - 1再进行解引用,就得到了5。
- *(a+1),a是数组名,是数组首元素,指向的对应图中紫色a,那么a+1,就对应图中紫色的a+1,对它进行解引用,得到的就是2。
- 最终的打印结果就是:2,5
练习题2
代码如下:
//指针运算练习题2
//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥?
#include<stdio.h>
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p = (struct Test*)0x100000;
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
运行结果:
分析:
- 注意,题目要求是在X86环境下运行的。
- p+0x1,0x1是16进制也就是1,p是结构体指针,+1就是跳过一个结构体,结构体的大小是20个字节,最后打印:00100014
- (unsigned long)p + 0x1,p的类型是无符号长整形,对它进行+1,最后打印:00100001
- (unsigned int*)p + 0x1,p的类型是无符号整型指针,+1,就跳过了一个整型的大小,最后打印:00100004
练习题3
代码如下:
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}
运行结果:
分析:
- 通过调式我们得到下图:
- 我们可以看到,这是一个二维数组,对二维数组初始化我们应该用花括号,但是,代码中使用的是圆括号。这其实是一个逗号表达式,逗号表达式取的是最后的值,所以就得到上图。
- a[0]表示数组首元素,那么数组首元素就是1。然后赋值给指针变量p,最后打印得到1
练习题4
代码如下:
//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
运行结果:
分析:
- 要求是在x86环境下,我们用画图来解析;
- &p[4][2] - &a[4][2] , 得到的是-4,但是打印是%p,以地址的形式打印出来是不在乎原反补码的,所以打印的是-4的补码以%p的形式打印出来,所以得到:FFFFFFFC。
- 以%d的形式打印,就得到-4。
练习题5
代码如下:
#include <stdio.h>
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1);
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
运行结果:
分析:
- 我们画图分析:
- 这是一个二维数组,我们已经在图上画出,&aa是数组的地址,+1跳过了一个数组。然后赋值给了整型指针变量ptr1,ptr1-1就得到了10。
- aa是数组首元素,+1,指向了aa[1] , 赋值给了ptr2,ptr2-1,就得到了5
练习题6
代码如下:
#include <stdio.h>
int main()
{
char* a[] = { "work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
运行结果:
分析:
- 这是一个指针数组,把a给了char ** pa这是个二级指针,pa++自增,指向了at,打印是字符串格式,最后输出at。
练习题7
代码如下:
#include <stdio.h>
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是指向蓝色线c+3的,然后++cpp,指向了红色线c+2,解引用得到了point。
- 看下图,因为之前的自增,cpp已经指向了红色线c+2,++cpp紫色线指向了c+1,解引用得到了c+1,然后自减得到了c,再进行解引用,得到了enter,那么指向了e,然后+3,最后得到er。
- 看下图,之前是指向紫色线c+1,*cpp[-2] = *(cpp-2) ,指向了橙色线,进行解引用得到了first,然后+3,最后打印st。
- 看下图,之前是指向橙色线c+3,然后cpp[-1][-1]+1 = * (* (cpp-1) -1) + 1 , 指向了粉色线c+1,解引用得到了new,进行+1,最后打印ew。
总结
- 以上就是今天要讲的内容,总共讲了7个练习题,希望对各位老板能有所帮助!
- 也希望各位老板,能够点个赞和一个关注,这是对我莫大的鼓励 ~