当前位置: 首页 > news >正文

C:数组传参的本质

 

1、一维数组传参的本质

数组传参是指在函数调用时将数组作为参数传递给函数。

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

数组传参只需要写数组名就可以了。注意:数组名是arr,而不是arr[10]

数组传参形参该怎么写呢?

void test(int arr[])//元素个数写不写无所谓

等下会说为什么写不写都不影响

现在我们来分别在(test)函数外部与函数内部计算数组元素的个数、

来,展示!

8b492435519d4d83ba2df923a0a2f2c0.png

可以看到在函数内部sz2结果为1,而函数外部sz1结果为10;这是为什么呢?

关于sz1 = 10;的结果我们都清楚,sizeof(arr)求得数组的总大小,sizeof(arr[0])求得数组首元素的大小,然后得出元素个数,但是为什么在test函数内部求得的元素个数结果变为1了呢?

我们来逆推一下,首先sizeof(arr[0])表示的是数组首元素的大小是不变的,因此sizeof(arr[0])等于4

sz2 = sizeof(arr) / 4 = 1;因此sizeof(arr)也等于4,那么在什么情况下能得到aizeof(arr) = 4 呢?

在数组传参的时候 test(arr);我们传递的是整个数组吗?还记得前面关于数组名的理解吗?这里arr既不是在sizeof中,前面也没有&符号,所以,test(arr)中的arr指的就是数组首元素的大小,因此我们传参过去的是首元素的地址,这便是一维数组传参的本质,既如此,我们便可以明白aizeof(arr) = 4是怎么得到的了,地址在32位机器上占4个字节,在64位机器上占8个字节 ,小编是在32位上操作的,所以最终得到izeof(arr) = 4 的结果。

void test(int arr[])//元素个数写不写无所谓
{int sz2 = sizeof(arr) / sizeof(arr[0]);printf("sz2 = %d\n", sz2);
}
#include <stdio.h>
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;}

 综上:数组传参传递的就是首元素地址

1.我们传递的不是整个数组,函数形参的部分是不会真实创建数组的,所以就不需要数组大小,也就是形参部分元素大小写不写都无所谓,没有什么影响

2.数组传过去的是数组首元素地址,地址应该拿指针来接收,所以函数形参部分应该使用指针变量来接收,而我们写成int arr[])是为了更加方便我们的理解。

void test(int arr[])可以写为void test(int* arr)

注意:

一维数组传参的时候,形参可以写成数组的方式,主要是为了方便理解,形参也可以写成指针变量的方式 

如果我们想要在函数内部获取数组元素的个数,该怎么写呢?

void test(int arr[10],int sz)
{//遍历数组int i = 0;for (i = 0; i < sz; i++){printf(" %d ", arr[i]);}
}
#include <stdio.h>
int main() 
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);test(arr,sz);return 0;
}

ef9309fad49f41a09dff5243b6b43356.png

2、二维数组传参的本质

理解二维数组传参的本质

二维数组传参本质上也是传递了地址,传递的是第一行这个一维数组的地址。

我们先来看一个二维数组传参的代码:

#include <stdio.h>
#include <string.h>
void print(int arr[3][5],int a,int b)
{for (int i = 0; i < a; i++) //遍历行数{for (int j = 0; j < b; j++)//遍历列数{printf("%d ", arr[i][j]);}printf("\n");//换行} 
}
int main()
{int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7, };print(arr, 3, 5);return 0;
}

7a5efdb1b3c048c0a63daeeaa29fb76d.png

上列代码中实参是⼆维数组,形参也写成⼆维数组的形式,那我们该怎么理解二维数组传参的操作呢?

071bf622141049d1ae720a4ca11c0c9e.png 从上图中,我们可以看到二维数组传参传递的也是数组名,数组名是什么呢?

数组名是数组首元素的地址,所以二维数组实参传递的是地址,既然传递的是地址,那么形参也就可以使用指针来接收。

这里你可能又会有一个疑问,二维数组的数组名到底是表示谁的地址?也就是二维数组的首元素是什么?

这里我们就需要对二维数组做一些更深入的理解了,前面关于数组的介绍篇章也说过

关于二维数组,我们可以把一维数组当作是数组的元素,那么这时候的数组就是二维数组

 

 1 12345 12345
 int intintintintint 23456
         34567
数组元素一维数组   intintintintint
          二维数组 

 所以我们可以这么理解:

二维数组其实是一维数组的数组,二维数组的每一个元素都是一维数组

这样我们就可以把二维数组的每一行看作是一个元素,所以二维数组的首元素就是它的第一行

二维数组的数组名表示的就是第一行的一维数组的地址。

675ad527cf984cd4a89563b4a00044cb.png

也就是说我们二维数组实参传过去的就是一维数组的地址

形参部分如果想要写成指针的方式,该怎么写呢?

由于实参传递的是数组的地址,所以形参应该使用数组指针来接收

表达形式:int  (*arr)[5],还记得为什么这么写吗?

arr与*结合说明arr是指针,指针指向的是数组 [5]说明数组有5个元素,每个元素类型是int

(*arr)是因为需要arr先于*结合。如果不使用圆括号,arr就不再是指针变量,而是会与[5]结合变为数组名。

C:指针学习-指针变量—学习笔记-CSDN博客

如果对于数组指针有一些不明白的地方,可以看一看这篇文章哟!

参部分用指针改写后:void print ( int(*arr)[5] , int a, int b)

二维数组在内存中是连续存放的,所以

1 2 3 4 5       

2 3 4 5 6                 可以理解为    1 2 3 4 5  2 3 4 5 6  3 4 5 6 7 

3 4 5 6 7                                     

e55fc320961c4061b440078d3f8e7db3.png

到这里是否能够理解二维数组传参的本质了吗?

二维数组传参传递的不是二维数组,而是二维数组首元素的地址,也就是第一行的地址,所以形参的部分要拿数组指针来接收。

 使用指针访问到二维数组的全部元素

图片文字较小,还请见谅,当时画完后没注意到,抱歉抱歉!可以放大观看,如有不理解的地方,也可以私我,我们一起探讨!

cc7fd1b12196462080fe5b60643c1b37.png

代码就可以改写成这样: 

void print(int(*arr)[5], int a, int b)
{for (int i = 0; i < a; i++){for (int j = 0; j < b; j++){printf("%d ", *(*(arr + i)+j));}printf("\n");} 
}

是不是感觉这样写不是很好理解,还可以换一种方式写*(*(arr + i)+j)

*(*(arr + i)+j)也可以写成arr[i][j]

这两种一种是指针的方式,一种使用数组下标的方式。

3、总结:

数组传参传递的都是地址,所以形参都可以使用指针来接收

一位数组传参传递的是首元素地址,使用(类型)指针来接收,

二维数组传参传递的是一维数组的地址,使用数组指针来接收。


本篇文章到这里就结束了,希望能够对大家理解数组传参有所帮助!

 

相关文章:

C:数组传参的本质

1、一维数组传参的本质 数组传参是指在函数调用时将数组作为参数传递给函数。 int main() {int arr[10] { 1,2,3,4,5,6,7,8,9,10 };test(arr);return 0;}数组传参只需要写数组名就可以了。注意&#xff1a;数组名是arr&#xff0c;而不是arr[10] 数组传参形参该怎么写呢&am…...

excel 2019版本的index match搜索功能

{TEXTJOIN("", TRUE, IF((sheet2!A:A"文字")*(sheet2!C:CC5), sheet2!G:G, ""))} excel单元格输入公式后&#xff1a; TEXTJOIN("", TRUE, IF((sheet2!A:A"文字")*(sheet2!C:CC5), sheet2!G:G, "")) 按CtrlShi…...

【问题解决】apache.poi 3.1.4版本升级到 5.2.3,导出文件报错版本无法解析

【问题解决】apache.poi 3.1.4版本升级到 5.2.3&#xff0c;导出文件报错无法解析 3.1.4版本代码&#xff1a; /*** 创建workbook* param inp* return* throws Exception*/public Workbook createworkbook(InputStream inp) throws Exception {if (!inp.markSupported()) {inp…...

(亲测有效)SpringBoot项目集成腾讯云COS对象存储(2)

接上文&#xff08;亲测有效&#xff09;SpringBoot项目集成腾讯云COS对象存储&#xff08;1&#xff09;-CSDN博客 目录 3、通用能力类 文件下载 测试 3、通用能力类 文件下载 官方文档介绍了2种文件下载方式。一种是直接下载 COS 的文件到后端服务器&#xff08;适合服务…...

界面优化 - QSS

目录 1、背景介绍 2、基本语法 3、QSS 设置方式 3.1 指定控件样式设置 代码示例: 子元素受到影响 3.2 全局样式设置 代码示例: 使用全局样式 代码示例: 样式的层叠特性 代码示例: 样式的优先级 3.3 从文件加载样式表 代码示例: 从文件加载全局样式 3.4 使用 Qt Desi…...

实现基于TCP协议的服务器与客户机间简单通信

服务器端程序 #include <myhead.h> #define SER_PORT 6666 //服务器端口号 #define SER_IP "192.168.2.53" //服务器ip地址 int main(int argc, char const *argv[]) { /*创建套接字 int socket(int domain, int type, int protocol);*/ …...

在uniapp中使用navigator.MediaDevices.getUserMedia()拍照并上传服务器

产品提了这样一个需求&#xff1a; 移动端拍照上传后图片不保存在用户设备上&#xff0c;试了好几种方法&#xff0c;uni-file-picker、uni.chooseImage、input type‘file’&#xff0c;安卓手机都会默认把图片保存在手机&#xff0c;于是各种查资料&#xff0c;找到了以下方法…...

PULLUP

重要提示&#xff1a;PULLUP属性已被弃用&#xff0c;应替换为PULLTYPE 财产。 PULLUP在三态输出或双向端口上应用弱逻辑高&#xff0c;以防止 它从漂浮。PULLUP属性保证逻辑高电平&#xff0c;以允许三态网络 以避免在不被驱动时漂浮。 输入缓冲器&#xff08;如IBUF&#xff…...

【无标题】乐天HIQ壁挂炉使用

这里写自定义目录标题 1.按键①&#xff1a; 按一下&#xff0c;小液晶显示的温度是所设定的供暖温度&#xff1b; 按二下&#xff0c;小液晶显示的温度是所设定的生活热水温度&#xff1b; 按三下&#xff0c;小液晶显示的温度是所设定的室内温度&#xff1b; 如果忘记按几下的…...

使用Python编写AI程序,让机器变得更智能

人工智能&#xff08;AI&#xff09;是当今科技领域最热门的话题之一。随着Python编程语言的逐渐流行&#xff0c;它已经成为许多人工智能编程的首选语言。本文将介绍如何使用Python编写AI程序&#xff0c;让机器变得更智能。 首先&#xff0c;Python提供了大量的AI库和工具&a…...

VScode + PlatformIO 和 Keil 开发 STM32

以前经常使用 KEIL 写 STM32 的代码&#xff0c;自从使用 VScode 写 ESP32 后感觉 KEIL 的开发环境不美观不智能了&#xff0c;后面学习了 VScode 开发 STM32 。 使用过程中发现 串口重定向在 KEIL 中可以用&#xff0c;搬到 VScode 后不能用&#xff0c;不用勾选 Use Micro LI…...

PostgreSQL 练习 ---- psql 新增连接参数

目标 添加一个连接参数&#xff0c;默认为 false 。当 psql 连接时&#xff0c;若该连接参数非 “true” 时&#xff0c;用户 “u1“ 对表对象无操作权限&#xff0c;包括自己拥有的表。 连接机制简介 连接过程如下所述&#xff1a; 客户端初始化一个空连接&#xff0c;设置…...

pdf翻译软件哪个好用?多语言轻松转

想知道怎么用pdf翻译器在线翻译吗&#xff1f;无需复杂操作&#xff0c;一键即可解锁语言障碍。 在这个全球化日益加深的时代&#xff0c;掌握pdf文件的快速翻译技巧尤为重要。 无论是学习、工作还是国际交流&#xff0c;以下4个免费pdf翻译技巧都将是你不可或缺的得力助手。…...

培训第三十天(ansible模块的使用)

上午 ansible是⼀种由Python开发的⾃动化运维⼯具&#xff0c;集合了众多运维⼯ 具&#xff08;puppet、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量 系统配置、批量程序部署、批量运⾏命令等功能。 1、学习ansible的使用 ansible 主机ip|域名|组…...

关于Log4net的使用记录——无法生成日志文件输出

关于Log4net的使用记录 前言遇到的问题具体使用总结前言 最近在使用log4net进行日志记录,保存一些需要的数据,以便后期使用需要。在使用的时候出现没有生成日志文件,针对这些问题,发现解决的办法! 遇到的问题 报错,提示没有找到对应的文件。 log4net:ERROR Failed to f…...

golang Kratos 概念

"Kratos"指的是一个开源的微服务框架&#xff0c;它用于构建高性能和可扩展的云原生应用。Kratos框架提供了一套丰富的工具和库&#xff0c;旨在简化微服务的开发和维护。下面是Kratos框架的一些基本概念&#xff1a; 服务构建与注册&#xff1a; gRPC与HTTP服务&…...

入门 MySQL 数据库:基础指南

简介 MySQL 是一个非常流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;广泛用于 Web 应用、企业应用和数据仓库。本博客将引导你从零开始&#xff0c;学习 MySQL 数据库的基础知识。 什么是 MySQL&#xff1f; MySQL 是一个基于 SQL&#xff08;Str…...

【Hexo系列】【3】使用GitHub自带的自定义域名解析

上一期我们通过学习【Hexo系列】【2】使用Vercel加速Hexo博客访问使用Vercel进行GitHub同步与加速&#xff0c;有时候Vercel也不太稳定访问不了。本身GitHub也是支持自定义域名的&#xff0c;本次教程将讲解如何使用GitHub自带的自定义域名解析。 1. GitHub设置 1.1 登录GitH…...

智能监控,无忧仓储:EasyCVR视频汇聚+AI智能分享技术为药品仓库安全保驾护航

随着科技的飞速发展&#xff0c;药品仓库的安全管理正迎来前所未有的变革。药品作为直接关系到公众健康的重要物资&#xff0c;其安全存储和监管显得尤为重要。在这个背景下&#xff0c;视频汇聚平台EasyCVR视频智能管理系统的应用&#xff0c;为药品仓库的安全监管提供了强有力…...

本地创建PyPI镜像

背景: 在安装一些库时,经常需要反复下载包(有的体积比较大,所以会比较慢),所以考虑在本地创建一个pypi镜像,把常用的库缓存下来,这样安装就会很省事.比较从本地安装库和从服务器下载会快很多. 安装使用 安装:pip install devpi 初始化: devpi-init --serverdirF:\pypioutput…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...