指针面试笔试题练习

您所在的位置:网站首页 spark基础笔试题及答案 指针面试笔试题练习

指针面试笔试题练习

2023-03-11 02:31| 来源: 网络整理| 查看: 265

在这里插入图片描述

前言

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍c语言中有关指针更深层的知识. 金句分享: ✨星光不问赶路人,✨ ✨时光不负有心人。✨

目录 前言笔试题1文字解释1:图解1: 笔试题2文字解释2: 笔试题3文字解释3:图解3: 笔试题4文字解释4: 笔试题5文字解释5:图解5: 笔试题6图解6: 笔试题7笔试题8(难度提升)分析1: ** ++cpp分步动态图解1: 分析2:*-- * ++cpp + 3分步动态图解2: 分析3:*cpp[-2] + 3分步动态图解3: 分析4:cpp[-1][-1] + 1分步动态图解4:

笔试题1

题目1:

#include 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

文字解释1:

a是数组名,类型为int[5],则&a类型为int(*)[5],当&a+1时,一次会跳过5个整形数据,则指向a数组的最后一个元素的后一个位置,ptr - 1刚好指向a数组的最后一个元素,解引用(星号)就会得到整形数字5. a+1表示数组的第二个元素,所以解引用得到整形数字2.

图解1:

在这里插入图片描述

笔试题2

不了解指针运算的可以点击这里哦! [传送门] 考点:指针+1,跳过的步长

题目2:

#include //已知结构体Test的大小是20字节 struct Test { int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }*p; int main() { p = (struct Test*)0x100000;//假设p 的值为0x100000。 printf("%p\n", p + 0x1);//0x100020 printf("%p\n", (unsigned long)p + 0x1);//0x10 printf("%p\n", (unsigned int*)p + 0x1); return 0; }

在这里插入图片描述 运行结果:

00100014 00100001 00100004

文字解释2:

p + 0x1: 因为p是一个结构体指针,结构体的大小是20个字节,所以p+0x1会跳过20个字节,20转化为16进制表示是14.

(unsigned long)p + 0x1: 这里需要注意的是,这里将p强制转化为无符号长整形,并不是无符号长整形指针,所以,+0x1只是正常的+1,就好比1+1=2,就只是变量之间的正常+1.

(unsigned int*)p + 0x1 将p指针强制转化为无符号整形指针,因为无符号整形是四个字节,则+0x1会跳过四个字节,转化为16进制4.

笔试题3

题目3: 环境:x86 小端环境

#include 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

文字解释3:

ptr1 因为&a + 1表示跳过a数组,指向a数组最后一个元素的后一个位置. ptr1[-1]等价于 *(ptr-1),即解引用得到数组的最后一个元素4.

ptr2:需要注意的是,向后偏移了一个字节. (int)a + 1,表示将a强制转化为int整形,整形+1就是正常的+1,则会向后偏移一个字节, (int*)((int)a + 1)再强制转化为整形指针,在小端存储模式下,会从首元素1(占四个字节)的第二个字节开始,向后读取四个字节(红色框框).这时按16进制打印出来就是2000000了.

图解3:

在这里插入图片描述

笔试题4 #include int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int* p; p = a[0]; printf("%d", p[0]); return 0; }

运行结果:

1

文字解释4:

是不是感觉很奇怪,不应该是0吗? a[0]表示二维数组的第一行的数组名,那么p[0]就等价于a[0][0],就是0呀. 实际本题考察重点是在逗号表达式. ? ? ? 这才是二维数组的初始化:用的是{} int a[3][2] = { {0, 1 }, {2, 3}, {4, 5} }; 而上面用的是(),则编译器会认为是逗号表达式,只保留后面的结果. 等价于: int a[3][2] = { (0, 1), (2, 3), (4, 5) }; ====== int a[3][2] = { 1, 3, 5 }; 故二维数组的初始化结果是 1 3 5 0 0 0 第一行第一个元素是1.做题要仔细哦,掉坑里了.

笔试题5

题目:

#include 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; }

在这里插入图片描述 运行结果:

FFFFFFFC,-4

文字解释5:

a是二维数组的数组名,类型是int ()[5],一次跳过五个整形 p是一个数组指针,类型是int()[4],一次跳过四个整形, a[4][2]与p[4][2]之间差了4个字节,即&p[4][2] - &a[4][2]=-4; -4按"%p"形式打印.会认为内存中的数据是内存.-4在内存中是按补码存的.

-4 1000 0000 0000 0000 0000 0000 0000 0100原码 1111 1111 1111 1111 1111 1111 1111 1011反码 1111 1111 1111 1111 1111 1111 1111 1100补码 转化为16进制表示地址后:F F F F F F F C

图解5:

在这里插入图片描述

笔试题6

题目:

#include 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; }

解释: 看图理解方便(偷个懒)

图解6:

在这里插入图片描述

笔试题7

题目:

#include int main() { char* a[] = { "work","at","alibaba" }; char** pa = a; pa++; printf("%s\n", *pa); return 0; }

在这里插入图片描述 运行结果:

at

解释:

a是一个字符指针,类型是char*,a+1会跳过一个char类型. pa是一个二级指针,类型是char**,pa+1会跳过一个char*.即指向数组的第二行,%s从该地址处向后打印直到遇到’\0’.

动图解析:

在这里插入图片描述

笔试题8(难度提升) #include int main() { char* c[] = { "ENTER","NEW","POINT","FIRST" }; char** cp[] = { c + 3,c + 2,c + 1,c }; char*** cpp = cp; printf("%s\n", **++cpp); //1 printf("%s\n", *-- * ++cpp + 3); //2 printf("%s\n", *cpp[-2] + 3); //3 printf("%s\n", cpp[-1][-1] + 1); //4 return 0; }

在这里插入图片描述 运行结果:

POINT ER ST EW

解释分析: 需要注意的是,当进行自增(++)或者自减(–)时,会真正改变指针的值,从而影响后面的语句.而加减整数或者访问元素([ ])并不会改变指针本身.并不会对后面的语句造成影响.

c是一个字符指针,+1会跳过一个字符(1字节). cp是一个指向一级字符指针的二级指针,+1可以跳过一个char*类型指针. cpp是一个指向cp的三级指针,+1会跳过一个二级指针.

分析1: ** ++cpp

原始状态图: 在这里插入图片描述

++cpp会跳过一个二级指针,并且是真正改变cpp指针的内容, 即cpp会指向cp的第二个元素,c+2 *++cpp表示得到c+2的地址 **++cpp表示得到c+2的值,即P的地址,按%s打印会得到,POINT.

分步动态图解1:

在这里插入图片描述

分析2:*-- * ++cpp + 3

注意!!! cpp由于1的改变,现在指向的是c+2.

原始图2: 在这里插入图片描述

++cpp会使cpp指向c+1(cp的第二个元素). *++cpp得到c+1的地址 - - *++cpp表示c+1的地址–,会会指向c *-- * ++cpp 会得到c的地址 *-- * ++cpp + 3表示指向E 按%s打印会打印ER.

分步动态图解2:

在这里插入图片描述

分析3:*cpp[-2] + 3

注意!!! 因为2的改变,此时cpp指向的是c+1.

图三原始图: 在这里插入图片描述

cpp[-2]等价于*(cpp-2),表示访问cpp指向的元素,往前找两个位置,即cp的第一个元素,c+3, *cpp[-2]解引用得到c+3的地址. *cpp[-2] + 3,表示指向c+3的第3个字符. 按%s打印,结果为ST

分步动态图解3:

在这里插入图片描述

分析4:cpp[-1][-1] + 1

注意!!! 3只是[-2]访问,并没有改变cpp本身. 原始图四:(与图三一样) 在这里插入图片描述

cpp[-1]等价于*(cpp-1),表示访问cpp指向的内容的前一个,即c+2(cp的第二个元素). cpp[-1][-1]表示访问c+2地址的前一个,即N地址处. cpp[-1][-1] + 1表示从N地址的下一个地址,E开始. 按%s打印是EW

分步动态图解4:

在这里插入图片描述 这次的指针面试题练习就讲到这里,希望对各位有所帮助. 886. 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3