【C语言】8道经典指针笔试题(深度解剖)

您所在的位置:网站首页 c语言深度解剖 【C语言】8道经典指针笔试题(深度解剖)

【C语言】8道经典指针笔试题(深度解剖)

2023-08-30 00:41| 来源: 网络整理| 查看: 265

上一篇我们也介绍了指针的笔试题,这一篇我们趁热打铁继续讲解8道指针更有趣的笔试题,,让大家更加深刻了解指针,从而也拿下【C语言】指针这个难点!

本次解析是在x86(32位)平台下进行

所需储备知识

sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。除此之外所有的数组名都表示首元素的地址。指针关系运算

笔试题1

以下代码结果是什么!?

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 *ptr = (int *)(&a + 1); (&a = int( *)[5]) &a取出了整个数组地址,&a+1跳过整个数组(ptr并没有解引用,所以不会造成越界访问)7e0b4776caa34421b1fe75f409ffd6eb.png

*(a + 1) ,a是数组名,数组名代表首元素地址,首元素地址+1,跳到下一个元素2的地址,在解引用。 第一个输出结果答案是->2

*(ptr - 1),ptr此时指向了组最后一个元素地址的下一个地址, -1又回到了最后一个元素地址,解引用。第二个输出结果答案是->5

笔试题2

以下代码结果是什么!?

struct Test { int Num; char *pcName; short sDate; char cha[2]; short sBa[4]; }*p; 假设p 的值为0x100000。 如下表表达式的值分别为多少? 已知,结构体Test类型的变量大小是20个字节 int main() { printf("%p\n", p + 0x1); printf("%p\n", (unsigned long)p + 0x1); printf("%p\n", (unsigned int*)p + 0x1); return 0; }

解析:

0x1 就是十六进制 1

printf(“%p\n”, p + 0x1);

p是一个结构体指针类型,结构体类型+1 跳过一个结构体大小,单位是字节。

所以p+1跳过20个字节,答案是-> 0x100014 .(十六进制14 代表十进制20)

printf(“%p\n”, (unsigned long)p + 0x1);

p 强制类型转换成(无符号整形),整型+1就是+1.

所以整型p+1跳过一个字节 .答案是->0x100001

printf(“%p\n”, (unsigned int*)p + 0x1);

p 强制类型转换成(整型指针类型),整型int指针+1,跳过一个整型。

答案是->0x100004

笔试题3

以下代码结果是什么!?

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

代码可能在x64位平台下编译不过 ,请换成x86(32)位平台

解析:

int *ptr1 = (int *)(&a + 1);

&a取出整个数组的地址,+1跳过整个数组

int *ptr2 = (int *)((int)a + 1);

a强制类型转换成 (整型),整型+1就是+1,跳过一个字节

printf( “%x,%x”, ptr1[-1], *ptr2);

图析:

91cf495383ed491a8d423c2f968f6363.png

所以ptr1[-1]答案->是 4

*ptr2 答案是-> 02 00 00 00

笔试题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; }

解析:

大家看清楚了! {}括号里面的()是逗号表达式,逗号表达式只算最后一个元素,所以int a【3】【2】 实际放的是 {1,3,5,0,0,0}

p = a[0] p是一个指针变量,a【0】 (a没有单独放在sizoef内部,代表的是二维数组首元素地址,二维数组首元素是第一行的地址, 那a是第一行了,a[0] 又是 第一行第一个元素a【0】【0】)。

所以 p[0] 是第一个元素,答案是->1

笔试题5

以下代码结果是什么!?

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

解析:

图析:

344cbd46ed6b457888038abb4e9dd85a.png

d4bc166818ac4d9886e90a0049d4bc76.png

答案是->-4 FFFFFFFC

笔试题6

以下代码结果是什么!?

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

解析:

int *ptr1 = (int *)(&aa + 1);

&aa取出整个数组的地址,+1跳过aa数组,来到10元素后面的位置。

int * ptr2 = (int *)( *(aa + 1));

aa代表首元素地址(二维数组首元素地址是第一行地址),首元素地址+1就是第二个行的地址,在解引用。

540d0c19db31422ea032fab07cd8a8a0.png

*(ptr1 - 1)

ptr1-1 指向了元素10(&a[1][4])的地址, 解引用找到10,答案是->10

*(ptr2 - 1)

ptr2-1 指向了后面5(&a[0][4])的地址,在解引用。答案是->5

以下代码结果是什么!?

笔试题7

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

解析:

*pa

其实该题把代码内存部图画出来就很容易解出来了,如下

d951595d65bf4e4f8bc452facd49f76f.png

笔试题8

以下代码结果是什么!?

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

该题比较复杂,要先画出内存部图才分析,不然很难做对

解析:

内该代码存部图(一步步画图分析)

79e26ea2d6a54ca1ae8ba57b8e781174.png

1

printf(“%s\n”, * * ++cpp);

先加加cpp,此时cpp指向了c+2在解引用找到c+2在解引用找到ROINT

答案是->ROINT. 内存部图如下(1)

image

2:

printf(“%s\n”, * - - * ++cpp+3);

先++cpp ,此时cpp指向了c+1在解引用找到了c+1再减减c+1 变成了c解引用C 找到了ENTERENTER+3 指向了E

最后以%s打印 答案是->ER 。内存部图如下(2)

image

3:

printf(“%s\n”, *cpp[-2]+3);

cpp[-2] = * (cpp-2)

cpp[-2] , 此时cpp找到了c+3并解引用(cpp并没有指向他)c+3在解引用找到了 FIRSTFIRST+3 指向了S

最后以%s打印 答案是->ST 。内存部图如下(3)

image

4:

printf(“%s\n”, cpp[-1][-1]+1);

cpp[-1][-1] = *( *(cpp-1)-1)

*(cpp-1) 此时指向了 c+2 (cpp并没有指向他)*( *(cpp-1)-1) 把c+2再减1 (变成c+1)在解引用找到了NEWNEW + 1 指向了E

最后以%s打印 答案是->EW 。内存部图如下(4)

image

完!

总结:

把二维数组当成一维数组来看待。题目就没有那么抽象指针类型加减运算决定了,对指针解引用的时候有多大的权限(能操作几个字节)如果不是单独放在sizeof()内部,一般的操作都会使指针降一阶对于抽象的指针一定要画图理解,不然很难做出。



【本文地址】


今日新闻


推荐新闻


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