C 深入指针(3)

news2025/1/12 13:30:26

目录

一、关于数组名

1 数组名的理解

 2 数组名 与 &数组名 的区别

二、使用数组访问指针

三、一维数组传参的本质

四、二级指针

五、指针数组

六、指针数组模拟二维数组 


一、关于数组名

1 数组名的理解

//VS2022 x64
#include <stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	printf("%p\n", &arr[0]);	//%p 打印地址
	printf("%p\n", arr);
	return 0;
}
//输出
//00000005302FFC78
//00000005302FFC78

【注意】有两个例外

  1. sizeof(数组名),sizeof 中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
  2.  & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)
#include <stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	printf("%p\n", arr);
	printf("%p\n", &arr);
	return 0;
}
//输出
//000000CC3238FA38
//000000CC3238FA38
//可以看到 &arr 打印的也是首元素地址

 2 数组名 与 &数组名 的区别

#include <stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	printf("%p\n", arr);
	printf("%p\n", arr + 1);
	printf("===================\n");
	printf("%p\n", &arr);
	printf("%p\n", &arr + 1);
	return 0;
}
//输出
//0000006E731EF618
//0000006E731EF61C
//===================
//0000006E731EF618
//0000006E731EF62C

//注意:地址是十六进制数,相减后要转换成十进制数才是相差字节数
//例子:2C-18 = 14;  转十进制:1*16^1 + 4*16^0 = 20

(1)arr 和 arr+1 相差4个字节,是因为 arr 是首元素的地址,+1就是跳过一个元素。

(2)但是 &arr 和 &arr+1 相差20个字节,这就是因为&arr是数组的地址,+1 操作是跳过整个数组的。

其实跟指针一样,指针规定类型就是为了确定一步走多大,这里也是一样,不明白这句话可以看C 认识指针-CSDN博客 的指针+-整数;


二、使用数组访问指针

#include <stdio.h>
int main()
{
	int arr[5] = { 0 };
	int* p = arr;
	for (int i = 0; i < 5; i++)	//输入
	{
		scanf("%d", p + i);	//等同于 &arr[i] 或者 arr+i
	}
	for (int i = 0; i < 5; i++)	//输出
	{
		printf("%d ", *(p + i));	//等同于 arr[i] 或者 p[i]
	}
	return 0;
}
//输入 1 2 3 4 5
//输出 1 2 3 4 5

可以看到 p[i] 等同于 *(p + i), 可以正常打印;同理 arr[i] 等价于 *(arr+i)。

【原因】

数组元素的访问在编译器处理的时候,都是转换首元素的地址+偏移量求出元素的地址,然后解引用来访问的。


三、一维数组传参的本质

#include <stdio.h>
void test(int arr[])
{
	int sz2 = sizeof(arr) / sizeof(arr[0]);
	printf("sz2 = %d", sz2);
}

int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int sz1 = sizeof(arr) / sizeof(arr[0]);
	printf("sz1 = %d\n", sz1);
	test(arr);
	return 0;
}
//输出
//sz1 = 5
//sz2 = 2

我们发现在 test函数内部 是没有正确获得数组的元素个数。

因为 数组名是数组首元素的地址;那么在数组传参的时候,传递的是数组名,也就是说本质上数组传参传递的是数组首元素的地址。

所以函数形参的部分理论上应该使用指针变量来接收首元素的地址。在test函数内部的 sizeof(arr) 计算的是一个地址的大小(单位字节)而不是数组的大小(单位字节)。

【总结】

一维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。


四、二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里? 这就是二级指针 。

#include <stdio.h>
int main()
{
	int a = 10;
	int* p = &a;
	int** pp = &p;

	int b = 20;
	*pp = &b;	//将 p 存放的地址改为 &b
	printf("%d\n", **pp);	
	return 0;
}
//输出
//20

五、指针数组


六、指针数组模拟二维数组 

#include <stdio.h>
int main()
{
	int arr1[5] = { 1,2,3,4,5 };
	int arr2[5] = { 2,3,4,5,6 };
	int arr3[5] = { 3,4,5,6,7 };
	//数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中
	int* parr[3] = { arr1,arr2,arr3 };	//指针数组在这里
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			printf("%d ", parr[i][j]);
			//等同于 *( *(parr + i) +j)
			//1、*(parr + i) 等同于parr[i],找到 parr数组中第i个元素
			//2、假如 i = 0,那就是 *(arr1 + j),不就是前面讲的,相当于arr1[j]
            //3、合在一起就是parr[i][j]
		}
		printf("\n");	//打印完一行换行
	}
	return 0;
}
//输出
//1 2 3 4 5
//2 3 4 5 6
//3 4 5 6 7

【注意】

上述的代码是模拟出二维数组的效果,实际上并非完全是二维数组,因为每一行并非是连续的,而二维数组在内存中的存放是连续的。


完 

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

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

相关文章

Cesium 问题:billboard 加载未出来

文章目录 问题分析问题 接上篇 Cesium 展示——图标的依比例和不依比例缩放,使用加载 billboard 时,怀疑是路径的原因导致未加载成功 分析 原先

知名专业定制线缆知名智造品牌品牌推荐-精工电联:如何实现清扫机器人线缆产品的精益求精

在科技日新月异的今天&#xff0c;智能清扫机器人已经融入我们的日常生活。然而&#xff0c;其背后不可或缺的一部分&#xff0c;就是那些被称为机器人血管的精密线缆。精工电联作为高科技智能化产品及自动化设备专用连接线束和连接器配套服务商&#xff0c;致力于通过精益求精…

用户行为分析与内容创新:Kompas.ai的数据驱动策略

在数字化营销的今天&#xff0c;用户行为数据分析已成为内容创新和策略调整的核心。通过深入理解用户的行为模式和偏好&#xff0c;品牌能够创造出更具吸引力和相关性的内容&#xff0c;从而实现精准营销。本文将探讨用户行为数据分析在内容创新和策略调整中的价值&#xff0c;…

Langchain实战

感谢阅读 LangChain介绍百度文心API申请申请百度智能云创建应用 LLMChain demo以及伪幻觉问题多轮对话的实现Sequential ChainsSimpleSequentialChainSequentialChainRouter Chain Documents ChainStuffDocumentsChainRefineDocumentsChainMapReduceDocumentsChainMapRerankDoc…

JavaEE 初阶篇-深入了解 HTTP 协议

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 HTTP 协议概述 2.0 HTTP 请求协议 2.1 请求方式的具体体现 3.0 HTTP 响应协议 3.1 常见的状态码及描述 3.2 常见的响应头 4.0 HTTP 协议解析 4.1 简单实现服务器响…

win11环境下,Idea 快捷键shift+f6重命名无法使用

微软自带输入法导致 单击win弹出搜索框

Java数据结构---栈和队列

目录 栈&#xff08;Stack&#xff09; 队列&#xff08;Queue&#xff09; 循环队列 栈&#xff08;Stack&#xff09; 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除操作元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一…

【启明智显分享】7寸HMI智能屏应用方案:Model4芯片实现展会多媒体互动展示

所谓&#xff1a;“技术是底层逻辑&#xff0c;用户是中心动力”。技术水平不断提升&#xff0c;人们对展会展览的形式和体验不断提出更多的要求&#xff0c;展会展现形式也正在不断地寻求突破。 传统的展示形式往往只能提供静态显示和有限的互动体验&#xff0c;在这个公众注意…

因表别名引用错误导致查询SQL执行时间长未出结果

问题描述&#xff1a; 项目组人员反馈在执行一条提取数据SQL时执行很慢&#xff0c;每次执行一段时间就报超时&#xff0c;要求帮忙提取下。 解决过程&#xff1a; 项目组人员发来SQL后&#xff0c;看了下SQL&#xff0c;没什么问题&#xff0c;就在客户端上执行了下&#xff0…

Antd Table组件,state改变,但是render并不会重新渲染

背景 在table上面&#xff0c;当鼠标放在cell上面的时候&#xff0c;需要去请求接口拉取数据&#xff0c;然后setList(res.result)后&#xff0c;希望render中的traceIds也能够实时更新渲染。 const [traceIds, setTraceIds] useState() // 需要展示在popover上面的数据&…

社媒营销中的截流获客是怎么一回事?

如果你要问&#xff0c;现在做社媒营销是通过哪些方式进行引流的&#xff0c;那么必然有一种是截流&#xff0c;顾名思义也就是分取别人的流量&#xff0c;方法其实很简单&#xff0c;主要分为两种&#xff1a;&#xff08;1&#xff09;抓取别人的粉丝出来进行群发私信&#x…

2024上海国际地下空间工程与技术展览会

2024上海国际地下空间工程与技术展览会 2024 Underground Space Project and Technology Expo 时间&#xff1a;2024年10月30日-11月1日 地点&#xff1a;上海世博展览馆 主办单位&#xff1a;联合国人居署 上海市住房与城乡建设管理委员会 城博会背景 上海国际城市与建筑…

mysql数据库---操作数据库跟表的命令总结

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文着重整理mysql管理库跟表的指令。 不涉及增删查改等指令 其实本篇主要是我做好笔记格式 用的时候直接复制粘贴的 所以排版大多是为了快速找功能来排的 方便大家快速找目标语法 数据库的简介 一个数据库系…

(代码以上传,超级详细)面试必备算法题----Leeecode290单词规律

文章目录 概要题目要求测试and提交结果技术细节 概要 来自Leecode ​ 代码已上传&#xff09;仓库&#xff0c;需要测试实例和其他题型解决&#xff0c;可以去自行浏览 点击这里进入仓库领取代码喔&#xff01;顺便点个star给原子加油吧&#xff01; ​ 题目要求 使用哈希表 …

国内外主流大模型都具备有哪些特点?

文章目录 ⭐ 火爆全网的大模型起点⭐ 国外主流LLM及其特点⭐ 国内主流LLM及其特点⭐ 全球大模型生态的发展 该章节呢&#xff0c;我们主要是看一下关于国内外主流的大语言模型&#xff0c;通过它们都具备哪些特点&#xff0c;来达成对多模型有一个清晰的认知。对于 “多模型” …

tensorflow报错

参考 TensorFlow binary is optimized to use available CPU instructions in performance-critical operations._this tensorflow binary is optimized to use availab-CSDN博客 解决Python中cuBLAS插件无法注册问题_unable to register cudnn factory: attempting to re-CS…

获取两个时间之间的月份

工具类 public static List<String> getMonthBetweenDate(Date startDate, Date endDate) {ArrayList<String> result new ArrayList<String>();SimpleDateFormat sdf new SimpleDateFormat("yyyy.MM");//格式化&#xff0c;调整为自己需要的格…

LED显示屏控制器5个问题和解答

在LED电子显示屏的使用和维护过程中&#xff0c;用户经常会遇到各种技术问题。以下是五个关于LED电子显示屏控制器的常见问题及其解答&#xff0c;由专业LED显示屏生产厂家提供&#xff0c;旨在帮助用户更好地理解和使用LED显示屏。 1. 嵌入式实时脱机二合一控制器的工作原理 嵌…

cmake工程导入新电脑环境报错

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 在一台电脑上运行得很好的cmake工程&#xff0c;导入新电脑环境报错 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 例如&#xff1a;数据传输过程中数据不时出现丢失的情况&…

从零开始!学习绘制3D表情的详细指南

在2020 年的苹果全球开发者大会(WWDC)&#xff0c;苹果发布了新的 macOS 11(又名 Big Sur)。其中在UI视觉方面macOS Big Sur 系统最大的变化就是图标上&#xff0c; Big Sur更新了很多新设计风格的 3D应用图标&#xff0c;3D设计的确可以提升UI整体的视觉氛围&#xff0c;并且现…