当前位置: 首页 > news >正文

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

上一篇我们也介绍了指针的笔试题,这一篇我们趁热打铁继续讲解8道指针更有趣的笔试题,,让大家更加深刻了解指针,从而也拿下【C语言】指针这个难点!
本次解析是在x86(32位)平台下进行

文章目录

  • 所需储备知识
  • 笔试题1
  • 笔试题2
  • 笔试题3
  • 笔试题4
  • 笔试题5
  • 笔试题6
  • 笔试题7
  • 笔试题8
  • 总结:

所需储备知识

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

笔试题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并没有解引用,所以不会造成越界访问)
在这里插入图片描述

*(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);
图析:在这里插入图片描述

所以ptr1[-1]答案->是 4
*ptr2 答案是-> 02 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;
}

解析:

大家看清楚了! {}括号里面的()是逗号表达式,逗号表达式只算最后一个元素,所以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;
}

解析:

图析:
该内存代码布局:
在这里插入图片描述
答案是->-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就是第二个行的地址,在解引用。

在这里插入图片描述

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

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


以下代码结果是什么!?

笔试题7

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

解析:

*pa

其实该题把代码内存部图画出来就很容易解出来了,如下
在这里插入图片描述


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

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

解析:

内该代码存部图(一步步画图分析)
在这里插入图片描述

  • 1

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

  1. 先加加cpp,此时cpp指向了c+2
  2. 在解引用找到c+2
  3. 在解引用找到ROINT
    答案是->ROINT. 内存部图如下(1)
    在这里插入图片描述
  • 2:

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

  1. 先++cpp ,此时cpp指向了c+1
  2. 在解引用找到了c+1
  3. 再减减c+1 变成了c
  4. 解引用C 找到了ENTER
  5. ENTER+3 指向了E
    最后以%s打印 答案是->ER 。内存部图如下(2)
    在这里插入图片描述
  • 3:

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

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

  1. cpp[-2] , 此时cpp找到了c+3并解引用(cpp并没有指向他)
  2. c+3在解引用找到了 FIRST
  3. FIRST+3 指向了S
    最后以%s打印 答案是->ST 。内存部图如下(3)
    在这里插入图片描述
  • 4:

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

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

  1. *(cpp-1) 此时指向了 c+2 (cpp并没有指向他)
  2. *( *(cpp-1)-1) 把c+2再减1 (变成c+1)在解引用找到了NEW
  3. NEW + 1 指向了E
    最后以%s打印 答案是->EW 。内存部图如下(4)
    在这里插入图片描述

完!


总结:

  • 把二维数组当成一维数组来看待。题目就没有那么抽象

  • 指针类型加减运算决定了,对指针解引用的时候有多大的权限(能操作几个字节)

  • 如果不是单独放在sizeof()内部,一般的操作都会使指针降一阶

  • 对于抽象的指针一定要画图理解,不然很难做出。

相关文章:

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

上一篇我们也介绍了指针的笔试题&#xff0c;这一篇我们趁热打铁继续讲解8道指针更有趣的笔试题&#xff0c;&#xff0c;让大家更加深刻了解指针&#xff0c;从而也拿下【C语言】指针这个难点! 本次解析是在x86&#xff08;32位&#xff09;平台下进行 文章目录所需储备知识笔…...

操作系统内核与安全分析课程笔记【2】进程管理与调度

文章目录基本概念与关键数据结构进程管理进程生命周期进程的关系进程家族树线程组进程组与会话进程的创建与终止Linux中的线程基本概念与关键数据结构 进程&#xff1a;静态的&#xff0c;存储在磁盘上的代码与数据。 程序&#xff1a;动态的&#xff0c;执行程序的动态过程&am…...

看完书上的栈不过瘾,为什么不动手试试呢?

一.栈的基本概念1.栈的定义栈&#xff08;Stack&#xff09;&#xff1a;是只允许在一端进行插入或删除的线性表。首先栈是一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作。其中注意几点&#xff1a;栈顶&#xff08;Top&#xff09;&#xff1a;线性表…...

AbstractQueuedSynchronizer从入门到踹门

概念设计初衷&#xff1a;该类利用 状态队列 实现了一个同步器&#xff0c;更多的是提供一些模板方法&#xff08;子类必须重写&#xff0c;不然会抛错&#xff09;。 设计功能&#xff1a;独占、共享模式两个核心&#xff0c;state、Queue2.1 statesetState、compareAndSetSta…...

【项目实战】手把手教你Dubbo微服务架构中整合熔断限流组件Sentinel

一、背景 项目中需要引入Sentinel来实现限流,但是项目是基于Dubbo的微服务架构,我们都知道Sentinel是属于SpringCloudAlibaba组件下的限流中间件,基于Dubbo的微服务架构真的能够引入 Sentinel吗?带着疑惑的心情,实践了一把~ 二、使用说明 2.1 引入依赖文件 <!-- Se…...

图像主题颜色提取(Median cut)

前言 之前想对图片素材进行分类管理&#xff0c;除了打标签&#xff0c;还有一样是通过主题色进行分类。于是开始寻找能提取主主题色的工具&#xff0c;最后找到了大名鼎鼎的 Leptonica 库&#xff0c;其中就有中位切割算法的实现。下面附上中位切割算法的其它语言版本的实现。…...

Python 分支结构

Python 分支结构 应用场景 迄今为止&#xff0c;我们写的Python代码都是一条一条语句顺序执行&#xff0c;这种代码结构通常称之为顺序结构。然而仅有顺序结构并不能解决所有的问题&#xff0c;比如我们设计一个游戏&#xff0c;游戏第一关的通关条件是玩家获得1000分&#x…...

【C++知识点】文件操作

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;C/C知识点 &#x1f4e3;专栏定位&#xff1a;整理一下 C 相关的知识点&#xff0c;供大家学习参考~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;…...

VBA小模板,跨表统计的2种写法

目标 1 统计一个excel 文件里&#xff0c;多个sheet里的内容2 有的统计需求是&#xff0c;每个表只单表统计&#xff0c;只是进行批量操作3 有的需求是&#xff0c;多个表得某些行列累加等造出来得文件 2 实现方法1 &#xff08;可能只适合VBAEXCEL&#xff0c;不太干净的写法…...

部署问题 | 百度LAC安装部署清单

本项目实现基于LAC提供RESTAPI服务的最小化方案。 依赖&#xff1a; python-3.9.9 百度lac2.X fastAPI uvicorn 首先下载并安装python&#xff0c;本人选择3.9版本。 依次安装&#xff1a; 安装 vc vc_redist.x64.exe 64位&#xff1a;https://download.microsoft.com/…...

提高办公效率的免费网站有哪些

收藏一些免费好用的网站&#xff0c;在我们工作中需要用到的时候可以直接使用&#xff0c;提高我们的工作效率。小编就和大家分享10个可以提高我们办公效率的免费网站。 1.羽兔网软件下载-以设计类软件为主的免费软件下载网站 很多小白都不知道怎么下载软件&#xff0c;往往搜…...

前端开发者需要掌握的具体内容和步骤

第一部分:前端开发实践 前端的工作职称 下面是一个前端开发者在职业发展中各种职称的描述列表. 对于前端开发者最普遍的职称是 "前端开发者" 或者 "前端工程师", 可以根据任何包含 "前端", "客户端", "web UI", "CS…...

杨校老师课堂之基于File类的文件管理器

在日常工作中&#xff0c;经常会遇到批量操作系统文件的事情&#xff0c;通常情况下&#xff0c;只能手动重复的完成批量文件的操作&#xff0c;这样很是费时费力。 本案例要求编写一个文件管理器&#xff0c;实现文件的批量操作。 文件管理器具体功能要求如下&#xff1a; 用…...

java面试算法汇总-数组

数组 [程序一] 两数之和 &#xff1a;给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 class Solution {public int[] twoSum(int[] nums, int target) {Map<Integer,…...

Docker-Mysql主从复制

步骤 1、新建主服务器容器实例3307 docker run -d -p 3307:3306 --privileged=true -v /tmp/mysql_master/log:/var/log/mysql -v /tmp/mysql_master/data:/var/lib/mysql -v /tmp/mysql_master/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root --name mysql-master mys…...

(模拟)1241. 外卖店优先级

目录 题目链接 一些话 流程 套路 ac代码 题目链接 1241. 外卖店优先级 - AcWing题库 一些话 流程 // // 每经过 1 // 个时间单位&#xff0c;如果外卖店没有订单&#xff0c;则优先级会减少 1 // &#xff0c;最低减到 0 // &#xff1b;而如果外卖店有订单&#xff0c;则…...

Linux进程学习【进程地址】

✨个人主页&#xff1a; Yohifo &#x1f389;所属专栏&#xff1a; Linux学习之旅 &#x1f38a;每篇一句&#xff1a; 图片来源 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 Perseverance is not a long race; it is many short races one after another…...

系统调用——文件操作相关函数

1.open open, creat - open and possibly create a file or device 打开一个文件&#xff0c;也可能创建一个文件&#xff0c;返回文件描述符 //头文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //接口 int open(const char *pa…...

做互联网自媒体创业的月薪收入真的能过万吗?

搞自媒体创业有前途吗&#xff1f;收入月薪过万是真的吗&#xff1f; 自媒体创业是一种新兴的创业方法&#xff0c;它的远景十分广阔。自媒体创业能够让人们在自己的兴趣爱好和专业范畴上发挥自己的才能&#xff0c;一起也能够获得不错的收入。可是&#xff0c;月薪过万并不是…...

Kubernetes (k8s) 污点(Taint)、容忍介绍、示例

Kubernetes (k8s) 污点&#xff08;Taint&#xff09; 是一种机制&#xff0c;用于标记一个节点&#xff08;Node&#xff09;不可被调度的状态。它可以将一个污点标记添加到节点上&#xff0c;以防止 Pod 被调度到该节点上。污点可以用于实现各种策略&#xff0c;例如分离故障…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...