【指针笔试题(3)(完结篇)】


前言:
祝贺你披荆斩棘来到笔试题的最后一篇,相比前两笔试题不同的是,这篇笔试题更考验你的基础知识
是否扎实,是否真正地理解指针是什么,所以你准备好了吗?OK让我们喊一下干饭人的口号!

在这里插入图片描述

知识点回顾

  • 数组名就是首元素的地址
  • 当数组名为下面两种情况时有特殊含义:(1) sizeof(数组名),这里的数组名代表的是整个数组,计算的是整个数组的大小。(2) &数组 名,这里表示整个数组的地址,类型为一个数组指针类型,注意除了以上两种情况的是他表达形式,数组名都表示数组首元素的地址。
  • 二维数组名:二维数组名代表首行元素的地址
  • sizeof只关注占用空间的大小,单位是字节sizeof不关注类型,sizeof是操作符
  • strlen关注的字符串中\0的为止,计算的是\0之前出现了多少个字符,strlen只针对字符串,strlen是库函数,函数传参为指针。(3)要注意区分数组名单独放在关键字sizeof中和单独放在函数strlen中的区别,大概的内容就是,单独放在sizeof中时指的是计算整个数组的大小,而单独放在函数strlen中时则指的是数组首元素地址。
    拿下知识点

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

✔解答环节:这里要用到学习数组时的一个知识点那就是a[i]=*(a+i),所以第一个结果为a[1]=2
&a+1跳过了整个数组指向如位置,然后再强制类型转换为整形指针存放于整形指针ptr,所以
ptr-1指向数组下标为4的元素即a[4]=5,所以是出结果为(2 , 5)
在这里插入图片描述

笔试题2

题目:下列代码假设p 的值为0x100000。 如下表表达式的值分别为多少?
已知,结构体Test类型的变量大小是20个字节

struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}

解答环节:因为p是结构体指针,0x1是一个16进制的数字为1,p+1即跳过一个结构体
所以第一个表达式p+1=0x100020,第二个表达式中,p被强制转换成了一个整型数字
再加上0x1,所以第二个表示为0x100001,第三个表达式与第一个相似,只不过是将
结构体类型指针转化为整形指针,此时p访问权限为4个字节,所以第三个表达式为
0x100004(0x100014 0x100001 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;
}

解答环节:第一个表达式中(&a+1)在如图位置即跳过整个数组,在强制值类型转化成整形指针,又ptr1[-1]=*(ptr-1)
所以等于a[3]=4,第二个表达式相对要困难一点,首先要理解(int)a+1是什么意思,其实是将数组首元素地址转换成
整形再加1,那就相当于地址值加1,地址值加1又等于跳过一个字节,然后再转换为整形指针存放于ptr2中,如图
对ptr2解引用时从指向如图向后访问四个字节(假设机器为小端字节序存放),即(2 00 00 00)
图解

👀小结:是不是掉坑了呢,这道题主要容易忽略指针运算和整数运算的区别,以及大小端字节序在内存中的存放与读取
即小端:低字节放在低地址处,读取时从高地址向低地址读取,大端反之。

在这里插入图片描述

笔试题4

问题:下列代码的输出结果是?

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

解答环节:这道题一上来千万不可拿着数据就开始做,仔细观察的话数组中有逗号表达式,呃挺无语的对吧
所以实际数组{1,3,5,0,0,0},a[0]代表第一行数组首元素地址存放于p中,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;
}

解答环节:因为p是一个数组指针指向的数组有4个元素,具体解答见图
在这里插入图片描述
👀***小结:这道题主要是要理解int(p)[4],它是一个数组指针指向的数组有4个元素。**

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

解答:如图
在这里插入图片描述

在这里插入图片描述

笔试题7

问题:下列代码的输出结果是?

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

🔎解答:要注意的是数组a是一个指针数组,所以数组名是数组首元素地址也就是’w’的地址,所以
要存放在字符二级指针pa中,详如图(注意图中pa指向的是w的地址,不是直接指向字符w的)

好家伙累死我了,还有最后一道压轴题,坚持住!
在这里插入图片描述

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

解答:分四幅图便于理解
表达式一图解

表达式二图解

表达式三图解

表达式四图解
芜湖~~毁灭吧!
溜了溜了

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值