C语言------指针(2)

news2024/11/19 7:35:29

前面已经向大家介绍了指针的一些基本内容,接下来,就在再我来先大家讲解一下指针的其他内容。

1. 数组名的理解

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

在学习数组的过程中,我们肯定会写过以上代码,我们知道 int 是该数组的数据类型,[10] 是该数组的大小,arr是数组名,那数组名代表这什么吗?它除了是数组的名字之外,还有其他意义吗?

接着还是用代码来探索其意义

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("arr=%p", arr);
	printf("arr[0]=p", &arr[0]);
	return 0;
}

我们写出以上代码并运行,分别打印其地址,运行后我们惊奇的发现arr的地址和arr[0]的地址恰好一样,而arr[0]有恰好是首元素。由此。我们得出数组名不仅仅是数组的名字,其也是数组首元素的地址。

那是不是在所有情况下,数组名都是首元素地址吗?

答案肯定不是,有两种情况除外。

(1)sizeof(arr) ,当我们用sizeof()来计算数组的大小时,此时数组名代表的是整个数组。

我们还是用代码来直观感受一下

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz1 = sizeof(arr);
	printf("arr=%d\n", sz1);
	int sz2 = sizeof(arr[0]);
	printf("arr[0]=%d", arr[0]);
	return 0;
}

用sz1来存储arr的大小,用sz2存储arr[0]的大小( 数组中一个元素的大小)。

运行代码

发现sz1的值为40,恰好是整个数组的大小,说明此时数组名代表整个数组。

(2)&arr 当数组名放在取地址操作符后面时,此时数组名也代表着整个数组。

我们还是用代码直接感受

int* p1 = &arr;
int* p2 = &arr[0];
printf("&arr  =%p\n", &arr);
printf("&arr+1=%p\n", arr + 1);
printf("&arr[0]  =%p\n", &arr[0]);
printf("&srr[0]+1=%p\n", &arr[0] + 1);

分别对arr和arr[0]取地址,分别将其存于指针变量p1和p2中

运行代码发现,分别对其加1时,指针p1跳过了40个字节,而指针p2却只跳过了一个字节。

前面我们学过,指针变量的类型绝定了其加1减1,一次能跳过的大小。

所以只有当指针p1指向整个数组时,p1才可能一次跳过40个字节。所以当数组名在&操作符后面时,此时数组名也代表整个数组。

除了这两种情况外,数组名都代表数组首元素地址。

2.使用指针访问数组名

既然数组名可以代表首元素地址,那么就可以用指针变量来保存其地址。

所以当我们用数组名作为一个函数的实参时,其形参可以写成数组的形式也可以用指针变量来接收。

我们还是用代码直接感受一下

int main()
{
	int arr[5] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = arr;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		scanf("%d ", p + i); //这里arr本身就有 & 含义了,所以不用在家 &
	}
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
	}
	return 0;
}

 

从上面代码可以看出*(p+i)和arr[i]是等价的。

其实 *(p+i)写成p[i]也是可以运行的,所以说本质上*(p+i)是等同于p[i]的。

有个小技巧,我们可以将 [ ] 看成一个解引用操作符就好理解了。

总结:数组的访问,是以首元素地址的基础上进行的偏移量进行访问的。

3.一维数组传参的本质

当我们将一个一维数组传递给一个函数的时候,本质上如何传递的呢?接下来探讨一下。

以代码为例

void test(int arr[])
{
 int sz2 = sizeof(arr)/sizeof(arr[0]);
 printf("sz2 = %d\n", sz2);
}
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 int sz1 = sizeof(arr)/sizeof(arr[0]);
 printf("sz1 = %d\n", sz1);
 test(arr);
 return 0;
}

 

从代码运行结果发现,sz1的值和sz2的值并不相同。这是为什么呢?

哦,原来当我们将一个数组名传过去的时候,其实是传过去了一个地址,则形参的类型就是一个指针类型,所以当我们在test()函数里面计算arr的大小时,其实并不是计算数组的大小,而是计算了一个指针的大小。正因为函数部分参数是一个指针,所以导致我们无法在函数内部计算数组的大小。

 总结:一维数组传参时,形参部分可以写成数组形式,也可以写成指针形式。

4.二级指针

既然变量都有属于自己的地址,那么指针变量也有属于它自己的地址,那要用什么来存储指针变量呢?

那便是二级指针。

这就是一个二级指针和一个一级指针的关系图

当我们对二级指针进行解引用,得到的是一级指针的地址,再对二级指针进行一次接应用,我们就可以得到一级指针里面保存的内容。

5.指针数组

紧接着我们再来将一个特别的数组---------指针数组。

通俗易懂,指针数组就是一个用来存放指针的数组。

 

6.指针数组模拟二维数组

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	int* parr[] = { arr1,arr2,arr3 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d ", parr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

分析代码:

首先我们要清楚,二维数组本质上可以看成是有多个一维数组组成的,这里我们将每个数组的数组名都存储在一个指针数组中,其中arr1,arr2,arr3 分别是指针数组中的第1个,第2个,第3个元素,前面我们提到 [ ] 可以看成解引用操作符。假如我们对parr解引用一次,便得到了arr1,也就是arr1的首元素地址,在对其进行一次解引用,就进一步的到了arr1里面的内容。

简单来说,parr[1]就等于arr1,parr[1][i]就相当于arr[1][j]。后面的以此类推。

代码运行如下

以上就是我对数组名的理解。谢谢大家的观看。 

 

 

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

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

相关文章

[BT]BUUCTF刷题第8天(3.26)

第8天 Web [CISCN2019 华北赛区 Day2 Web1]Hack World 题目明确提示flag在flag表里的flag列&#xff0c;这里先尝试1 返回&#xff1a;你好&#xff0c;glzjin想要一个女朋友。 再尝试1&#xff0c;返回bool(false) 到这里就感觉是布尔盲注的题目类型了&#xff08;虽然我没…

GPT提示词分享 —— 代码释义者

提示词&#x1f447; 我希望你能充当代码解释者&#xff0c;阐明代码的语法和语义。 3.5版本&#x1f447; free2gpt 4.0版本&#x1f447; gpt4

深入解析快速排序算法

深入解析快速排序算法 一、快速排序算法简介二、快速排序算法过程三、快速排序算法示例四、快速排序算法分析1. 时间复杂度&#xff1a;2. 空间复杂度&#xff1a;3. 稳定性&#xff1a; 五、快速排序算法优化1. 优化基准元素的选择&#xff1a;2. 优化小数组的排序&#xff1a…

[HackMyVM]靶场Crossbow

kali:192.168.56.104 靶机:192.168.56.136 端口扫描 # nmap 192.168.56.136 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-26 22:17 CST Nmap scan report for crossbow.hmv (192.168.56.136) Host is up (0.0057s latency). Not shown: 997 closed tcp…

Spring IOC 容器循环依赖解决(三级缓存)

对于循环依赖的解决&#xff0c;首先得了解Spring IOC 容器的创建过程&#xff0c;在加载过程中&#xff0c;Bean 的实例化和初始化是分开的&#xff0c;所以在解决循环依赖的问题时&#xff0c;也是基于Bean 的实例化和初始化分开执行这一特点。 我们将实例化后的Bean 叫 半成…

2024中国闪存市场观察:AI助推闪存全面起势?

过去两年&#xff0c;闪存市场一直处于低迷状态&#xff0c;但去年第四季度闪存颗粒资源的上涨&#xff0c;导致闪存产品价格一路上扬&#xff0c;市场遂发生反转。 2024年&#xff0c;中国闪存市场会彻底走向复苏&#xff0c;还是急转直下&#xff1f;中国AI热潮&#xff0c;…

JavaScript原型、原型对象、原型链系列详解(五)

(五)、JavaScript原型设计模式 什么是JavaScript原型设计模式&#xff1f; 为什么要使用JavaScript原型设计模式&#xff1f; JavaScript原型设计模式的实现方法有哪些&#xff1f; JavaScript原型设计模式的应用场景是什么&#xff1f; 什么是JavaScript原型设计模式&#xff…

Raft 共识算法

什么是木筏&#xff1f; Raft 是一种共识算法&#xff0c;旨在易于理解。它 在容错和性能方面与Paxos相当。不同之处在于 它被分解成相对独立的子问题&#xff0c;而且它干净利落 解决了实际系统所需的所有主要部分。我们希望 Raft 能使 更广泛的受众可以达成共识&#xff0c;并…

【网站项目】303老年人的景区订票系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

主流公链 - Cosmos

探索Cosmos区块链&#xff1a;构建互联的区块链网络 1. Cosmos简介 Cosmos是一个开放的区块链互联协议&#xff0c;旨在解决区块链之间的孤立性问题。它的愿景是构建一个可以互相通信和互操作的区块链网络&#xff0c;实现资产和数据的流动性。在Cosmos中&#xff0c;不同的区…

langchain调用语言模型chatglm4从智谱AI

目录 ​0.langchain agent 原理 ReAct 1.langchain agent使用chatgpt调用tools的源代码 2.自定义本地语言模型的代码 3.其他加速方法 背景&#xff1a;如果使用openai的chatgpt4进行语言问答&#xff0c;是需要从国内到国外的一个客户请求-->openai服务器response的一个…

使用Nginx1.25.4版本做负载均衡、搭建Nacos2.3.0服务集群

关于使用版本问题上&#xff0c;其实小白更喜欢使用新的版本&#xff0c;因为新的版本功能更多&#xff0c;肯定优化方面不言而喻&#xff0c;懂得都懂&#xff0c;但是新的版本&#xff0c;肯定使用起来更加的速度&#xff0c;性能&#xff0c;也是不言而喻的啊&#xff0c;那…

力扣--并查集684.冗余连接

思路分析&#xff1a; 首先定义了一个Solution类&#xff0c;包含了私有成员变量fa[1001]和n&#xff0c;以及三个私有成员函数find()、togother()和findRedundantConnection()。 find()函数用于查找节点的根节点&#xff08;即所在连通分量的代表节点&#xff09;&#xff0c…

2024最新华为OD机试试题库全 -【二叉树的广度搜索】- C卷

1. 🌈题目详情 1.1 ⚠️题目 有一棵二叉树,每个节点由一个大写字母标识(最多26个节点)。 现有两组字母,分别表示后序遍历(左孩子->右孩子->父节点)和中序遍历(左孩子->父节点->右孩子)的结果,请你输出层序遍历的结果。 1.2 🔣输入要求 每个输入文…

CMC学习系列 (2):EEG-EMG有可能作为运动恢复的生物标志物

CMC学习系列:EEG-EMG有可能作为运动恢复的生物标志物 0. 引言1. 主要贡献2. 方法2.1 显著 bins 数量2.2 偏侧性指数 3. 结果3.1 临床评估3.2 CMC3.3 卒中后CMC随时间变化 4. 讨论和结论5. 总结欢迎来稿 论文地址&#xff1a;https://www.frontiersin.org/journals/neurology/ar…

信号处理--基于混合CNN和transfomer自注意力的多通道脑电信号的情绪分类的简单应用

目录 关于 工具 数据集 数据集简述 方法实现 数据读取 ​编辑数据预处理 传统机器学习模型(逻辑回归&#xff0c;支持向量机&#xff0c;随机森林) 多层感知机模型 CNNtransfomer模型 代码获取 关于 本实验利用结合了卷积神经网络 (CNN) 和 Transformer 组件的混合…

在DasViewer里怎么查看三维模型的坐标系?

量测就可以查看坐标系了&#xff0c;或者查看xml文件中坐标系的代号。量测就可以查看坐标系了&#xff0c;或者查看xml文件中坐标系的代号。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅…

Go语言学习Day3:数据类型、运算符与流程控制

名人说&#xff1a;莫愁千里路&#xff0c;自有到来风。 ——钱珝 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、数据类型①布尔类型②整型③浮点型④string⑤类型转换 2、运算符①算术运算符②逻辑运算符③关…

STM32学习笔记(6_8)- TIM定时器的编码器接口代码

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 现在开…

원클릭으로 주류 전자상거래 플랫폼 상품 상세 데이터 수집 및 접속 시연 예제 (한국어판)

클릭 한 번으로 전자상거래 플랫폼 데이터를 캡처하는 것은 일반적으로 웹 페이지에서 정보를 자동으로 추출 할 수있는 네트워크 파충류 기술과 관련됩니다.그러나 모든 형태의 데이터 수집은 해당 웹 사이트의 사용 약관 및 개인 정보 보호 정책 및 현지 법률 및 규정을 준수…