C语言经典指针运算笔试题图文解析

指针运算常常出现在面试题中,画图解决是最好的办法。

题目1:

#include <stdio.h>
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得到的是整个数组的地址,其和首元素地址相同,但类型为 int (*) [5] ,对其 +1 ,跳过 5 * 4 = 20字节

然后对其强制类型转换为int*,此时其 -1 ,跳过 4 字节

故对其解引用得到数组中下标为 4 的元素,值为5。

数组名代表首元素地址,其 +1 就得到数组下标为 1 的元素的地址,对其解引用就得到对应元素,值为2。

题目2:

struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = (struct Test*)0x100000;

int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (long)p + 0x1);
	printf("%p\n", (int*)p + 0x1);
	return 0;
}

        p是类型为结构体类型的指针,那么其每 +-1 跳过一个结构体变量大小的空间,而此结构体变量大小为20个字节,那么p + 0x1 = 0x100014,以地址的形式打出也是0x100014,因为地址就是以16进制表示的

        当对其强制类型转换为long类型后,p不再代表地址,而是代表整数0x100000,对其 +0x1,就是简单的整数运算,得0x100001。

         当对其强制类型转换为int*类型后,p变为指向整形类型的指针变量,对其 +1,跳过4字节,故值为0x100004。

题目3:

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

一上来看到这样的数组形式,就会想当然的认为这个二维数组为:

这样的二维数组其书写格式应该为:a[3][2] = {{0,1},{2,3},{4,5}}

而原书写对行的划分使用的是小扩号,应理解为逗号表达式,其结果为a[3][2] = {1,3,5}。由于给出的元素没有达到二维数组元素总个数,剩下拿0来补齐,那么实为:

a[0] 为第一行首元素地址,p[0] == *(p + 0),那么这里最后访问到的应该为第一行第一列的元素,即1。

题目4:

//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
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;
}

a为一个五行五列存放元素为int类型的二维数组,p为int(*)[4]类型的数组指针,意味着其 +1 一次跳过4个int类型变量空间大小。

假设&p[4][2] = 0x00000001,那么&a[4][2] = 0x00000011,&p[4][2] - &a[4][2] = 0xFFFFFFFC,此为-4的16进制转换

我们知道,两指针相减的绝对值可以得到两指针间元素的个数,那么这里的元素个数就为4,由于是低地址位指针减高地址位指针,所以结果为负值

题目5:

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

&aa得到的是整个二维数组的地址,类型为int(*)[2][5],意味着 &aa + 1 一次跳过整个二维数组的内存空间大小。aa得到的是二维数组首元素的地址,即为第一行元素组成的数组的地址,类型为int(*)[5], 意味着对其 +1 直接指向第二行元素组成的数组,由于数组地址与数组首元素地址相同,此时aa + 1指向第二行元素组成的数组的首元素。

ptr1 此时指向的就为图示&aa + 1的位置,但由于其类型为int*,意味着其 -1仅跳过4字节,ptr1-1解引用得10;*(aa + 1)为int*类型,仍然是一个指针,只不过不再指向一个数组,而是一个整形变量,故ptr2指向了图示位置,解引用得5。

题目6:

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

a为数组名,代表数组首元素地址,而a数组为元素是字符串的数组,故每个元素实则为字符串首字符的地址,正因为是地址的地址,所以用二级指针pa来存。

对pa++解引用拿到"at"字符串的首字符的地址,故:

题目7:

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

同题六作图:

注:此题作图一定注意++ 、+的区别,一个会改变自身,一个不会。

**++cpp,首先对cpp + 1解引用得到c数组中第3个元素的地址,再解引用访问c数组中第3个元素,此元素为POINT字符串首字符的地址。

*--*++cpp+3,其先对cpp + 1,然后解引用得到cp第3个元素,即c第2个元素地址,然后对其--得到c第1个元素的地址,再解引用得到ENTER字符串的首字符地址,再+3就得到第4个字符的地址,从此字符开始打印,结果为ER。(ps.      ((*(--*(++cpp)))+3)   )

*cpp[-2]+3,cpp[-2]得到cp数组第一个元素,即c数组最后一个元素地址,再解引用得到FIRST字符串首字符地址,+3就得到S字符的地址,从此地址打印,得到ST。

cpp[-1][-1]+1,cpp[-1]得到cp的第2个元素,即c数组第3个元素的地址,再[-1]即对此地址-1解引用,得到字符串NEW的首字符地址,再+1得到E字符的地址,从此字符开始打印,结果为EW。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习 --- stanford cs231 编程作业(assignment1,Q3: softmax classifier)

stanford cs231 编程作业(assignment1&#xff0c;Q3: softmax classifier softmax classifier和svm classifier的assignment绝大多部分都是重复的&#xff0c;这里只捡几个重点。 1&#xff0c;softmax_loss_naive函数&#xff0c;尤其是dW部分 1&#xff0c;1 正向传递 第i张…

银河麒麟v10 sp3编译制作内核rpm包——筑梦之路

环境信息 下载内核源码包 这里下载4.19版本的内核源码包&#xff0c;当前最新为4.19.315 https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.315.tar.xz 准备编译环境 # 安装编译需要的依赖包yum install rpm-devel rpmdevtools yum groupinstall "Developmen…

AI写作助手:简化你的学术写作流程

在日常工作和生活中&#xff0c;我经常使用各种各样的人工智能工具&#xff0c;如AI写作助手、AI语音助手和AI绘图工具等。这些AI工具显著提升了我的工作效率&#xff0c;并极大地简化了我的日常任务。作为一名AI工具的忠实爱好者&#xff0c;我搜集了许多免费的AI工具&#xf…

OZON多少资金可以提现,OZON提现要求

在跨境电商领域&#xff0c;OZON平台凭借其卓越的服务和广泛的用户基础&#xff0c;吸引了众多卖家入驻。然而&#xff0c;对于许多新手卖家而言&#xff0c;关于OZON平台的资金提现问题仍然存在一定的疑惑。本文将详细解析OZON平台上的资金提现政策&#xff0c;帮助卖家们更好…

JAVA小知识15:JAVA到底是值传递还是引用传递?

java中是值传递还是引用传递&#xff1f; 结论&#xff1a;值传递 一、值传递、引用传递 先看一个例子&#xff1a; 在这个例子中函数private static void updata(int i)中的 i 就叫形参 updata(a)中的 a 就叫做实参 值传递&#xff1a;若改变了i的值&#xff0c;但是a的值不变…

2025年最值得期待数据安全保护系统

虽然具体到2025年的数据安全保护系统细节可能尚未完全公开&#xff0c;但从当前趋势和技术创新来看&#xff0c;可以预见一些关键特性和系统可能的发展方向。 1.防泄密软件安企神 持续的技术创新&#xff1a;安企神将继续采用并升级其先进的加密技术&#xff0c;确保数据在传输…

【Mybatis】关于Mybatis手写xml文件的常见问题

明天就是端午节啦 博主今天先提前祝大家端午节快乐呀&#xff01;&#xff01; 文章目录 前言一、尽量做到参数化查询二、关于param注解三、mybatis处理特殊字符1.转义字符2.<![CDATA[]]>&#xff08;CDATA 标记&#xff09; 四、结果映射1、映射好文件与接口 namespace2…

Docker 容器 mysql 配置主从

1、前提条件 集群的条件下 服务器 172.16.11.195 13316:3306 服务器 172.16.11.196 13317:3306 配置好主数据库和从数据 2、配置主从数据库 2.1使用portainer 来管理容器 建立数据库密码 新增配置文件 # mysql-master.cnf [mysqld] server_id110 log-binmysql-binrela…

android 开机动画执行流程

android深入了解开机动画 开机动画的种类 1&#xff1a;View绘制 2&#xff1a;逐帧动画&#xff1a;比较主流的方式&#xff0c;一般动画的文件打包成 bootanimation.zip 存储到 /system/media/ 下。一般.zip文件 > 5M 就会有明显的卡顿&#xff0c;所以一般开机动画只有…

【代码随想录】【算法训练营】【第36天】 [860]柠檬水找零 [406]根据身高重建队列 [452]用最少数量的箭引爆气球

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 36&#xff0c;周三&#xff0c;最难坚持的一天~ 题目详情 [860] 柠檬水找零 题目描述 860 柠檬水找零 解题思路 前提&#xff1a; 思路&#xff1a;维护5&#xff0c;10&#xff0c;20三种…

【教程】DGL单机多卡分布式GCN训练

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ PyTorch中的DDP会将模型复制到每个GPU中。 梯度同步默认使用Ring-AllReduce进行&#xff0c;重叠了通信和计算。 示例代码&#xff1a; 视频&#xff1…

【免费Web系列】大家好 ,今天是Web课程的第十九天点赞收藏关注,持续更新作品 !

1. Vue工程化 前面我们在介绍Vue的时候&#xff0c;我们讲到Vue是一款用于构建用户界面的渐进式JavaScript框架 。&#xff08;官方&#xff1a;Vue.js - 渐进式 JavaScript 框架 | Vue.js&#xff09; 那在前面的课程中&#xff0c;我们已经学习了Vue的基本语法、表达式、指令…

MapperStruct拷贝数据的介绍和使用

1、前言 在java 编程中&#xff0c;对象直接拷贝是很常用的方法&#xff0c;最初我们常用spring提供的拷贝工具BeanUtils的copyProperties方法完成对象之间属性的拷贝。但是它有几个明显的如下缺点 1、属性类型不一致导致摸一个属性值拷贝失败 2、通一个字段使用基本类型和包…

Mybatis plus join 一对多对象语法

1. 实体类环境 题目 package co.yixiang.exam.entity;import co.yixiang.domain.BaseDomain; import co.yixiang.exam.config.CustomStringListDeserializer; import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonCreator;…

使用Python爬取temu商品与评论信息

【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作&#xff01; 【&…

Pytorch--Convolution Layers

文章目录 1.nn.Conv1d2.torch.nn.Conv2d()3.torch.nn.ConvTranspose1d()3.torch.nn.ConvTranspose2d() 1.nn.Conv1d torch.nn.Conv1d() 是 PyTorch 中用于定义一维卷积层的类。一维卷积层常用于处理时间序列数据或具有一维结构的数据。 构造函数 torch.nn.Conv1d() 的语法如…

【运维自动化-配置平台】如何使用云资源同步功能(腾讯云为例)

云资源同步是通过apikey去单向同步云上的主机资源和云区域信息&#xff0c;目前支持腾讯云和亚马逊云。主要特性 1、蓝鲸配置平台周期性的单向只读同步云主机和vpc&#xff08;对应蓝鲸云区域&#xff09;信息&#xff0c;第一次全量&#xff0c;后面增量 2、默认同步到主机池…

kotlin 中的数字

以下均来自官方文档&#xff1a; 一、整数类型 1、kotlin中内置的整数类型&#xff0c;有四种不同大小的类型&#xff1a; 类型存储大小&#xff08;比特数&#xff09;最小值最大值Byte8-128127Short16-3276832767Int32-2,147,483,648 (-231)2,147,483,647 (231 - 1)Long64…

图片导入AutoCAD建立草图—CAD图像导入插件

插件介绍 CAD图像导入插件可将PNG&#xff0c;JPG等格式图片导入到AutoCAD软件内建立图像边缘的二维线条模型。插件可以提取图像黑色或白色区域的边界&#xff0c;并可绘制原状边界或平滑边界两种样式。 模型说明 边界提取&#xff0c;黑色或白色边界的提取根据原图类型选择…

c#调用c++dll方法

添加dll文件到debug目录&#xff0c;c#生成的exe的相同目录 就可以直接使用了&#xff0c;放在构造函数里面测试