【C语言】深入理解指针(3)数组名与函数传参

 


正文开始——数组与指针是紧密联系的

(一)数组名的理解

(1)数组名是数组首元素的地址 

 

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

        上述代码通过&arr[0] 的方式得到了数组第一个元素的地址,但其实数组名本身就是一个地址,并且是数组首元素的地址。

代码1:


#include<stdio.h>
int main()
{int arr[6] = { 1,2,3,4,5,6};printf("%p\n",arr);printf("%p\n",&arr[0]);return 0;
}

结果:

        数组名与数组首元素的地址打印出的结果是一样的。于是,数组名就是数组首元素(第一个元素)的地址。

(2)两个例外

代码2:

#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("%d\n", sizeof(arr));return 0;
}

结果:

         令我们出乎所料的是,这里的数组名不再是数组首元素的地址,而是表示整个数组。

对于代码中出现的数组名,不违背数组名是数组第一个元素的的地址,也就是说:

 

        数组名是数组首元素的地址是对的,但是有两个例外:

        • sizeof(数组名),sizeof中单独放数组名,这里的数组名代表整个数组,sizeof计算的是整个数组的大小,单位是字节
        • &数组名,这的数组名代表整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)

        除此之外,其他地方使用数组名,都代表的是数组首元素的地址。

那么,数组名与&数组名具体有什么区别?

        通过指针运算就可以体现出他们的区别:

代码3:

printf("&arr[0] = %p\n", &arr[0]);printf("&arr[0]+1 = %p\n", &arr[0]+1);printf("arr = %p\n", arr);printf("arr+1 = %p\n", arr+1);printf("&arr = %p\n", &arr);printf("&arr+1 = %p\n", &arr+1);

 结果:

        &arr[0] 和 &arr[0] + 1 相差4个字节,arr 和 arr + 1 相差 4个字节,原因是&arr[0] 和arr 都是数组arr 首元素的地址,通过指针运算 +1 就是跳过一个int型的元素(也就是跳过4个字节)。

        &arr 和 &arr + 1 相差40个字节,原因是&arr是数组的地址,指针运算 + 1 就是跳过整个数组 int   [10] 型元素(也就是10个整形,40个字节)。

 


(二)函数内数组传参

(1)一维数组传参 

         相信你一定使用过冒泡排序吧;

        将数组(传址)和数组内元素个数传给函数,

​
int main()
{int arr[10] = {5,4,8,7,9,6,3,2,1,0};int sz1 = sizeof(arr)/sizeof(arr[0]);Bobble_sort(arr,sz1);Print();return 0;
}​

就会得到排序好的数组。

        观察上述操作,我们都是在函数外部计算数组的元素个数,那我们可以把数组传给⼀个函
数后,函数内部求数组的元素个数吗?
 

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

结果:(在x86下)

         为什么传给函数的是数组,结果sizeof计算整个数组的的大小 = 4 字节呢?

        这就要学习数组传参的本质了,上个小节我们学习了:数组名是数组首元素的地址;那么在数组传参的时候,传递的是数组名,也就是说数组传参本质上传递的是数组首元素的地址。


        所以函数形参的部分理论上应该使用指针变量来接收首元素的地址。

void Bobble_sort(int* p,int sz)
{.......
}int main()
{int arr[5] = {1,2,3,4,5};int sz = sizeof(arr)/sizeof(arr[0]);Bobble_sort(arr,sz);return 0;
}

那么在函数内部我们写sizeof(arr) 计算的是⼀个地址的大小(单位字节)而不是数组的大小(单位字节)。正是因为函数的参数部分是本质是指针,所以在函数内部是没办法求的数组元素个数的。

(2)二维数组传参 

         二维数组传参,以上的结论仍成立:

           数组传参本质上传递的是数组首元素的地址。

二维数组的首元素,不再是一个基本的数据类型,而是一个数组类型。

什么是数组类型?

如果一个数组是整形数组,元素是5个整形,那么他的类型就是( int    [5] )类型。

二维数组首元素的地址其数据类型就是(int  (*)[5])类型。

 那么在主函数内(未传参)sizeof(二维数组的数组名)计算的就是整个二维数组大小;

传参后,sizeof(二维数组名)的结果就是指针(int  (*)[5])的大小了。(所有类型,函数,其地址的大小是一定的)

(3)三维及高维数组传参

        仍然满足   数组传参本质上传递的是数组首元素的地址。

这里我们来看一段代码:

#include<stdio.h>void PR(int (*p)[3][3])
{}
int main()
{int arr[3][3][3];PR(arr);return 0;
}

        解释:

        数组arr的首元素类型是int    [3][3],在传参的时候,可以用指针类型int(*)[3][3]来接收,类型是照应的。这也说明 arr传递的是首元素的地址


完~

未经作者同意禁止转载

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

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

相关文章

绿色制造的行业标杆OEKO-TEX STeP认证

STeP是“OEKO-TEX国际环保纺织协会”推出的一个独立的第三方认证体系。STeP全称Sustainable Textile & Leather Production&#xff08;可持续纺织和皮革生产&#xff09;&#xff0c;是面向纺织和皮革供应链中环保且负有社会责任的生产工厂推出的透明认证体系。 STeP认证的…

【Mybatis plus】使用分页查询,报错 Parameter ‘xxx‘ not found. Available parameters are xxx

文章目录 0 先给出错误场景java entity 实体类java mapper 接口方法Java mapper 所对应的 mapper.xml 信息异常信息 1 解决办法step1: 给 mapper 接口方法加上具名参数指定&#xff0c;如下&#xff1a;step2: 修改 mapper.xml 的查询信息&#xff0c;都加上 具名 限定 2 异常原…

快快销ShopMatrix 分销商城多端uniapp可编译5端-代理商收益管理:差价奖励和销售额统计

代理商收益管理是一种针对代理商的利润分配模式&#xff0c;主要通过差价奖励和销售额统计来实现。这种模式的核心思想是通过激励代理商的销售行为&#xff0c;提高代理商的积极性和销售效率&#xff0c;从而实现整个销售网络的增长。 差价奖励是代理商收益管理中的一种常见方…

电商系统设计到开发03 引入Kafka异步削峰

一、前言 系统设计&#xff1a;电商系统设计到开发01 第一版设计到编码-CSDN博客 接着上篇文章&#xff1a;电商系统设计到开发02 单机性能压测-CSDN博客 本篇为大制作&#xff0c;内容有点多&#xff0c;也比较干货&#xff0c;希望可以耐心看看 已经开发的代码&#xff0…

配置ARP安全综合功能示例

组网图形 ARP安全简介 ARP&#xff08;Address Resolution Protocol&#xff09;安全是针对ARP攻击的一种安全特性&#xff0c;它通过一系列对ARP表项学习和ARP报文处理的限制、检查等措施来保证网络设备的安全性。ARP安全特性不仅能够防范针对ARP协议的攻击&#xff0c;还可以…

uniapp点击事件报错 Cannot read property ‘stopPropagation‘ of undefined

问题产生&#xff1a;在列表上有个小按钮&#xff0c;可点击弹出选择框。 列表本身可点击进入详情页。所以想用click.stop来阻止点击小按钮时候&#xff0c;触发列表的点击事件。 结果&#xff1a;如图所示 解决方案&#xff1a;发现自己用的是icon&#xff0c;在icon上加click…

2. HarmonyOS 应用开发 DevEco Studio 准备-2

2. HarmonyOS 应用开发 DevEco Studio 准备-2 首选项设置 中文设置 主题 字体 插件安装和使用 保存时操作 编辑器 工程树管理 代码树管理 标记 字符串可视化编辑 参考文档 常用快捷键 编辑 查找或替换 编译与运行 调试 其他 预览 页面预览 自定义组件预览 预览…

[学习笔记] ONNX 基础知识

1. ONNX 简介 1.1 什么是 ONNX 开放神经网络交换 ONNX&#xff08;Open Neural Network Exchange&#xff09;是一套表示深度神经网络模型的开放格式&#xff0c;由微软和 Facebook 于 2017 推出&#xff0c;然后迅速得到了各大厂商和框架的支持。通过短短几年的发展&#xf…

文档 OCR 识别优化为异步思路逻辑

文档 OCR 识别优化 同步处理&#xff08;原逻辑&#xff09; 当前系统识别文档为同步处理&#xff0c;已调整过 python 服务部分参数&#xff0c;但 一份40M左右文档识别仍需要几十秒 文档转为图片集合for 循环中一直调用 ocr 识别 异步处理 nginx 增加 requestId header …

系统架构17 - 软件工程(5)

软件工程 系统测试测试原则测试方法静态测试动态测试黑盒测试白盒测试灰盒测试自动化测试 系统测试 软件测试是使用人工或自动的手段来运行或测定某个软件系统的过程&#xff0c;其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。 软件测试方法的分类有…

C++大学教程(第九版)7.19 将7.10节vector对象的例子转换成array对象

文章目录 题目代码运行截图 题目 (将7.10节vector 对象的例子转换成array 对象)将图7.26中 vector 对象的例子转换成使用array 对象。请消除任何 vector 对象仅有的特性。 分析&#xff1a; vector对象独有的特性&#xff1a; 1.vector对象长度可变 2.长度不同的vector对象可…

查看php-fpm占用内存情况

1、查看每个php-fpm占用的内存大小 ps -ylC php-fpm --sort:rss 2 查看单个php-fpm进程消耗内存的明细 pmap $(pgrep php-fpm) | less pmap pmap命令用于显示一个或多个进程的内存状态 pmap [ -x | -d ] [ -q ] pids 参数&#xff1a; -x extended Show the extended f…

蓝桥小白赛4 乘飞机 抽屉原理 枚举

&#x1f468;‍&#x1f3eb; 乘飞机 &#x1f437; 抽屉原理 import java.util.Scanner;public class Main {static int N 100010;static int[] a new int[N];public static void main(String[] args){Scanner sc new Scanner(System.in);int n sc.nextInt();int q s…

【Godot4自学手册】第七节背景搭建

各位同学&#xff0c;今天是第七节&#xff0c;在本节我会学习如何使用TileMap来完成背景搭建。 一、添加TileMap结点 先做个介绍&#xff0c;TileMap是基于 2D 图块的地图节点。Tilemap&#xff08;图块地图&#xff09;使用 TileSet&#xff0c;其中包含了图块的列表&#…

dvwa靶场文件上传high

dvwa upload high 第一次尝试&#xff08;查看是否是前端验证&#xff09;第二次尝试我的上传思路最后发现是图片码上传修改配置文件尝试蚁&#x1f5e1;连接菜刀连接 第一次尝试&#xff08;查看是否是前端验证&#xff09; 因为我是初学者&#xff0c;所以无法从代码审计角度…

JSON 字符串转换 —— Map、List

目录 转 Map maven 依赖 转换 转 List maven依赖 转换 转 Map JSON格式为 {key:value,key2:value2,......} maven 依赖 <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.28</version>…

三元运算符是什么?怎么用?

三元表达式又叫三元运算符&#xff0c;它必须要有三个操作数参与的运算 操作符号&#xff1a;&#xff1f; 表达式&#xff1a;在参与js程序时&#xff0c;都必须先计算出表达式结果&#xff0c;才能参与后续程序 语法&#xff1a;布尔表达式&#xff1f;true&#xff1a;fal…

Day34- 动态规划part02

一、不同路径 题目一&#xff1a;62. 不同路径 62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”…

「QT」QString类的详细说明

✨博客主页何曾参静谧的博客📌文章专栏「QT」QT5程序设计📚全部专栏「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「

Python实现自定义函数的5种常见形式分析

Python自定义函数是以def开头&#xff0c;空一格之后是这个自定义函数的名称&#xff0c;名称后面是一对括号&#xff0c;括号里放置形参列表&#xff0c;结束括号后面一定要有冒号“&#xff1a;”&#xff0c;函数的执行体程序代码也要有适当的缩排。Python自定义函数的通用语…