C语言指针笔试真题整理(8道)

news2024/11/26 5:32:05

前言

本篇文章整理了一些指针的笔试题,适合初学者以及对于指针掌握并不是很牢固的朋友阅读,当然,大佬想做着玩的话可以看一看第八题~

分类:循序渐进的难度:前三题和第七题是简单题,第四题有陷阱,5、6、8比较复杂(8最难)

希望能帮助到大家更好的理解指针,话不多说我们直接开始。

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

答案

2,5

解析

我们采用画图的方式来一步一步的分析

*(ptr - 1)

首先,明确&a+1在内存中的位置,(&a+1)是数组指针类型
在这里插入图片描述

其次,将(&a+1)转换成int*类型,再存储进整形指针ptr里,

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

位置如图
在这里插入图片描述

然后,ptr是整形指针,所以减一,ptr向前移动一个整型,就指向5了
那么,*(ptr - 1)存储的就是5了
在这里插入图片描述

*(a + 1)

a此处是首元素地址,加一指向2,解引用之后,结果就是2

2

题干

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

答案

0x00100014
0x00100001
0x00100004

解析

本题考察的就是不同类型的指针加一,结果是什么
小提示:
0x1虽然是十六进制,但还是1
p是指针,指针与整数的运算,移动多少位,取决于指针变量的大小

p + 0x1

p是结构体指针,大小是20个字节,
p + 0x1,就相当于加了20个字节,所以就是0x00100014

(unsigned long)p + 0x1

p转换成了整型,已经不是指针了,而整型与整数的运算就是直接的加减
所以结果就是0x00100001

(unsigned int*)p + 0x1

p转换成了无符号整型指针,加一,跳过一个无符号整型,四个字节
结果就是0x00100004

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

答案

4,2000000

解析

数组的存储方式如下
在这里插入图片描述

ptr1

(&a + 1),如图
在这里插入图片描述
之后,(int*)(&a + 1)将(&a + 1),转换成整型指针,再赋给ptr1

ptr1[-1]

转换一下:
ptr1[-1] == ptr+(-1)== *(ptr-1)
等于使prt1向前移动一个整型的大小,也就是4个字节
如图:蓝色箭头

在这里插入图片描述
所以打印结果就是0x4

ptr2

(int)a
将a强制转化成int类型,再加一,
之后再转换成整型指针,相当于较之前向后移动了一个字节
画个图方便大家理解
在这里插入图片描述
ptr2,就指向图中黄色的位置

*ptr2

ptr2是整型指针,解引用后能向后访问四个字节,粉色的四个字节

在这里插入图片描述

结果就是:0x2000000

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

解析

我们逐层来分析

()逗号表达式

注意,数组在初始化时没有用{},而用的是()
那么这里就是逗号表达式,我们都知道逗号表达式最后一个表达式为结果,

所以数组在初始化后,结果如下

在这里插入图片描述

p = a[0]

a[0]是第一行元素的数组名
并且,此时, a[0]既没有放在sizeof内,又没有取地址,
所以,这里的 a[0]指的就是第一行元素的首元素地址,就是1的地址

p[0]

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

答案

FFFFFFFC,-4

解析

此处为了方便理解和美观,我们将二维数组表示成一维数组

p[4][2]

p是指针数组,指向数组,数组里有四个元素,每个元素都是整型

图解:

在这里插入图片描述
p[4][2]就表示为

**(p+4+2

(p+4)指向的是一个有四个元素的数组,每个元素都是int类型,

*(p+4)之后得到这个有四个元素的数组,

那么*(p+4)就相当于数组名,也就是首元素的地址

加2之后,得到下图:

在这里插入图片描述

p = a

p指向的数组只有4个元素,但数组名a此时指向的是第一行元素,而第一行有五个元素,
放不下,只能放四个进去,所以在运行时,会报警告:
//p的类型可以表示为int(*)[4]

//a的类型可以表示为int (*)[5]

int (*)[4]”和“int (*)[5]”数组的下标不同

当然,程序这样也可以强行运行

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

a[4][2]

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

&p[4][2] - &a[4][2]

经过上面的解释,我们可以理解他们各自的含义
下面进行二者取出地址之后,再相减,也就是指针变量减指针变量
在这里插入图片描述
二者相减,得到的是他们之间的元素个数,为4

我们又知道,数据在存储时是从低地址向高地址存储的,所以, &p[4][2]更小,得到的结果是-4

%p与%d

%p

用%p的形式来打印的话,输出的是-4在内存中的存储形式,也就是补码
下面进行详细说明

//原码:
10000000000000000000000000000100
//反码:
11111111111111111111111111111011
//补码:
11111111111111111111111111111110

但是,这里解释一下%p
%p在打印时认为打印的是地址(这里可以简单地认为是无符号数),所以就直接以16进制的形式打印

11111111111111111111111111111110

提示:二进制中1111对应十六进制中的F

打印结果:
FFFFFFFC

%d

用%d的形式来打印的话,输出结果就是-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;
}

答案

10,5

解析

&aa + 1

取出二维数组的地址,再+1,跳过了这个二维数组,
&aa + 1是数组指针,要进行强制类型转换,转换成int*类型
在这里插入图片描述

*(aa + 1)

aa是数组名,表示的是二维数组的首元素,即第一行元素
(aa + 1)跳过了一行,指向的是第二行元素
解引用之后, *(aa + 1) == aa[1],也就是第二行元素的数组名,表示的是第二行首元素6的地址

在这里插入图片描述

*(ptr1 - 1)

ptr1是整型指针,减一之后,指向10,
解引用之后输出的结果是10
在这里插入图片描述

*(ptr2 - 1)

ptr2是整型指针,减一,指向5这个元素
在这里插入图片描述
多说一句:
ptr2在转换类型之前,就是int*类型,之后再进行类型转换可能只是为了形式美观

7

题干

#include<stdio.h>

int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;

	pa++;
	printf("%s\n", *pa);
	return 0;
}

答案

at

解析

温习旧识

字符指针

char *p = “abcdef”

该指针存储的是,该常量字符串的首元素a

a[]

a[],是字符指针数组,每个元素存储的都是字符串的首元素的地址,
如图:
在这里插入图片描述

a是数组名,存储的是首元素的地址,
即‘w’

pa

pa是二级指针变量,存储的是a数组首元素的地址

pa++,跳过的是pa指向元素的类型的大小,而它指向的元素类型是char*,指向的就是a数组中的第二个元素
,也就是at中a的地址

那么以字符串的形式打印*(pa),结果就是at

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

答案

POINT
ER
ST
EW

解析

很多朋友看到这道题可能想放弃,不要放弃,我们一步一步来分析

c[]

字符指针数组,四个元素,存储的分别是E、N、P、F的地址,
如图:
在这里插入图片描述

cp[]

二级字符指针数组,c是数组的数组名,即首元素的地址,
自己进行一一对应
在这里插入图片描述

cpp

三级指针,存储的是cp的地址,也就是cp首元素的地址
如图:

在这里插入图片描述

**++cpp

cpp先自增,如图
在这里插入图片描述
再解引用两次,第一次解引用获得c+2,第二次解引用获得字符P的地址
再以字符串的形式打印出point

*-- * ++cpp + 3

先计算++cpp
注意:此时cpp的生命周期没有结束,还在代码块之内
在这里插入图片描述
解引用获得c+1

再自减,变成c

此时再进行解引用,得到字符‘E’的地址,

最后+3(向后移动三位),此时指向的就是ENTER中的第二个E

最终输出结果就是ER

*cpp[-2] + 3

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

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

(cpp - 2)指向的是c+3
两次解引用之后,字符F的地址

+3,向后移动三位,是字符S的地址

打印结果是:
ST

cpp[-1][-1] + 1

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

cpp-1,指向的是c+2
如图
在这里插入图片描述
c+2,再减一,变成c+1

之后解引用获得字符N的地址,

加1,指向的是字符E,

最终打印的结果就是EW

结语

这8道题到这里就讲解结束了,怎么样,希望你有所收获

这类题作为笔试题,很强调自己对于画图能力的要求,这也是很重要的

我们下篇文章再见~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/875944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是Web应用程序防火墙,WAF与其他网络安全工具差异在哪?

一、什么是Web 应用程序防火墙 (WAF) &#xff1f; WAF软件产品被广泛应用于保护Web应用程序和网站免受威胁或攻击&#xff0c;它通过监控用户、应用程序和其他互联网来源之间的流量&#xff0c;有效防御跨站点伪造、跨站点脚本&#xff08;XSS攻击&#xff09;、SQL注入、DDo…

最新版本 Stable Diffusion 开源 AI 绘画工具之 VAE 篇

✨ 目录 &#x1f388; 什么是VAE&#x1f388; 开启VAE&#x1f388; 下载常见的VAE&#x1f388; 对比不同VAE生成的效果 &#x1f388; 什么是VAE VAE&#xff1a;是 Variational Auto-Encoder 的简称&#xff0c;也就是变分自动编码器可以把它理解成给图片加滤镜&#xff…

ChatGPT or BingChat

你相信我们对大模型也存在「迷信权威」吗&#xff1f; ChatGPT 的 GPT-4 名声在外&#xff0c;我们就不自觉地更相信它&#xff0c;优先使用它。但我用 ChatALL 比较 AI 大模型们这么久&#xff0c;得到的结论是&#xff1a; ChatGPT GPT-4 在大多数情况下确实是最强&#xf…

【elementUi】绘制自定义表格、绘制曲线表格

要求绘制下图系列表格&#xff1a; 实现步骤: 1.绘制树&#xff0c;实现树勾选字段—>表格绘制字段 逻辑&#xff1a; 树&#xff1a;check-change“treeChart.handleCheckChange” 绑定点击选择事件&#xff0c;改变data.column3数据项&#xff1b;表格:columns"data…

Unity智慧园区夜景制作

近期使用Unity做了一个智慧园区场景的demo&#xff0c;初步了解了3D开发的一些步骤和知识&#xff0c;以下为制作的步骤&#xff0c;比较简略&#xff0c;备忘&#xff1a; 1. 制作前的设计分析&#xff1a; 1. 分析日光角度&#xff0c;阴影长度&#xff0c;效果 2. 分析冷暖…

Idea 快捷键整理

Idea快捷键和自动代码补全汇总 idea快捷键汇总 Ctrl 快捷键说明Ctrl F在当前文件进行文本查找 &#xff08;必备&#xff09;Ctrl R在当前文件进行文本替换 &#xff08;必备&#xff09;Ctrl Z撤销 &#xff08;必备&#xff09;Ctrl Y删除光标所在行 或 删除选中的行 &am…

双向最佳路径优先搜索算法

概念 双向最佳优先搜索&#xff08;Bidirectional Best-First Search&#xff09;是一种图搜索算法&#xff0c;用于在给定的图或树中找到两个节点之间的最短路径。该算法尝试从起始节点和目标节点同时扩展搜索&#xff0c;直到两个搜索方向相遇。 双向最佳优先搜索的步骤如下…

Rx.NET in Action 第三章学习笔记

3 C#函数式编程思想 本章内容包括 将 C# 与函数式技术相结合使用委托和 lambda 表达式使用 LINQ 查询集合 面向对象编程为程序开发提供了巨大的生产力。它将复杂的系统分解为类&#xff0c;使项目更易于管理&#xff0c;而对象则是一个个孤岛&#xff0c;你可以集中精力分别处理…

table 根据窗口缩放,自适应

element-plus中&#xff0c;直接应用在页面样式上&#xff0c; ::v-deep .el-table{width: 100%; } ::v-deep .el-table__header-wrapper table,::v-deep .el-table__body-wrapper table{width: 100% !important; } ::v-deep .el-table__body,::v-deep .el-table__footer,::v-d…

试卷转电子版怎样处理?分享个好用的扫描转换方法

试卷转电子版是一个常见的需求&#xff0c;可以通过扫描纸质试卷来实现。但是&#xff0c;扫描后的文件可能会有一些问题&#xff0c;例如模糊、颜色失真、文字识别错误等。在这篇文章中&#xff0c;我将分享一个好用的扫描转换方法&#xff0c;可以帮助您快速而准确地将试卷转…

Spring 中 @Qualifier 注解还能这么用?

文章目录 1. 基本用法1.1 指定 Bean 名称1.2 不指定 Bean 名称1.3 自定义注解1.4 XML 中的配置 2. 源码分析2.1 doResolveDependency2.2 findAutowireCandidates 3. 小结 今天想和小伙伴们聊一聊 Qualifier 注解的完整用法&#xff0c;同时也顺便分析一下它的实现原理。 说到 Q…

【运维知识高级篇】超详细的Jenkins教程1(安装部署+配置插件+创建自由风格项目+配合gitlab实现Jenkins自动触发)

Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成的工具&#xff0c;用于监控持续重复的工作&#xff0c; 旨在提供一个开放易用的平台&#xff0c;使软件的持续集成变成可能&#xff0c;是持续集成的核心&#xff0c;可以与其他软件进行协作&#xff0c;例…

为什么骑友对太过商业化的景点如此反感?

一骑友小李最近在社交媒体上分享了他的旅行经历。他去了一个著名的景点&#xff0c;原本期待满满&#xff0c;却发现这个曾经心中的旅行圣地已经变得过分商业化。小卖部、纪念品摊位、过度开发的风景……让他感到十分失望。他的故事引发了骑友们的热议&#xff0c;很多人表示深…

vue.draggable浅尝

介绍 Vue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动&#xff0c;可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作&#xff0c;总之是一款非常优秀的vue拖拽组件。本篇将介绍如何搭建环境及简单的…

网工最常犯的9大错误,越早知道越吃香

下午好&#xff0c;我的网工朋友 我们常说&#xff0c;人要学会避免错误&#xff0c;尤其是对在职场生活的打工人来说&#xff0c;更是如此。 学生时代&#xff0c;我们通过错题本收集错误&#xff0c;提高刷题正确率和分数&#xff0c;但到了职场&#xff0c;因为没有量化的…

2023年京东宠物食品行业数据分析(京东大数据)

宠物食品市场需求主要来自于养宠规模&#xff0c;近年来由于我国宠物数量及养宠人群的规模均在不断扩大&#xff0c;宠物相关产业和市场规模也在蓬勃发展&#xff0c;宠物食品市场也同样保持正向增长。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;2023年1月-7月&am…

Live Market:个人如何做跨境电商?带你从0到1了解跨境电商

跨境电商是指通过互联网技术&#xff0c;将商品从一个国家或地区销售到另一个国家或地区的商业活动。为消费者提供更加丰富、优质、实惠的商品选择&#xff0c;促进国际贸易的发展和经济的繁荣。跨境电商还可以帮助企业降低成本&#xff0c;提高效率&#xff0c;提升品牌知名度…

创建一个 React+Typescript 项目

接下来 我们来一起探索一下用TypeScript 来编写react 这也是一个非常好的趋势&#xff0c;目前也非常多人使用 那么 我们就先从创建项目开始 首先 我们先找一个 或者 之前创建一个目录 用来放我们的项目 然后 在这个目录下直接输入 例如 这里 我想创建一个叫 tsReApp 的项目…

【Java】2021 RoboCom 机器人开发者大赛-高职组(复赛)题解

7-8 人工智能打招呼 号称具有人工智能的机器人&#xff0c;至少应该能分辨出新人和老朋友&#xff0c;所以打招呼的时候应该能有所区别。本题就请你为这个人工智能机器人实现这个功能&#xff1a;当它遇到陌生人的时候&#xff0c;会说&#xff1a;“Hello X, how are you?”其…

终端里执行qtcreator命令报错xcb

使用rpm 安装libxkbcommon-x11-0.8.4-3.ky10.x86_64.rpm包