c语言基础:数组的运用以及在内存中的地址的理解

目录

目录:

1.数组作为函数参数

2.数组在内存中的存储

     2.1数组名是什么?

   

2.2下面我们来探讨二维数组的各个名字表示什么

二维数组的首元素地址是什么呢?

*arr表示的是什么呢 ?(arr是二维数组)


1.数组作为函数参数

为啥错了

void bubble_sort(int arr[])
{int sz = sizeof(arr) / sizeof(arr[0]);//这样对吗?int i = 0;for (i = 0; i < sz - 1; i++){int j = 0;for (j = 0; j < sz - i - 1; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}int main()
{int arr[] = { 3,1,7,5,8,9,0,2,4,6 };bubble_sort(arr);//是否可以正常排序?int i = 0;for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){printf("%d ", arr[i]);}return 0;
}

当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。

所以接收的是指针,指针的大小是4个字节,4/4=1,sz大小是1.

我们指针数组名就是首元素地址,毫无疑问,传参的时候arr传过去就是首元素地址,只是为了便于理解,我们说把数组传过去了,数组传过去了,我们拿一个数组接收,所以我们的形参写的是int arr[];但是,实际上我们写的规范一点应该写一个指针去接收, 

正确的冒泡排序:(在主函数算出sz,再传给形参。)

void bubble_sort(int arr[],int sz)
{int i = 0;for (i = 0; i < sz - 1; i++){int j = 0;for (j = 0; j < sz - i - 1; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}int main()
{int arr[] = { 3,1,7,5,8,9,0,2,4,6 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr,sz);//是否可以正常排序?int i = 0;for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){printf("%d ", arr[i]);}return 0;
}

2.数组在内存中的存储

     2.1数组名是什么?

我们已经知道数组是在内存中是连续存放的,内存为数组分配好空间,每个空间有具体的地址指向,

int arr[10] = { 1,2,3,4,5 };printf("%p\n", arr);//数组名printf("%p\n", &arr[0]);//第一个元素的地址printf("%d\n", *arr);//对数组名解引用

我们看看上面代码运行的结果

分析结果可知,数组名和第一个元素的地址一样,而且对地址解引用得到的结果也是第一个元素

结论:

数组名是数组首元素的地址。(但是有两个例外)

1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数 组。

2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。  

请大家熟记这两个例外,很多时候很容易错,在我很多博客也都写过这两个例外 

证明如下: 

   

int arr[10] = {0};
printf("%d\n", sizeof(arr));

我们知道如果此时数组是首元素地址,而sizeof 是计算所占内存空间的大小,单位是字节,一个地址存起来只需要4个字节,按理说答案是4,可以我们运行结果是

答案是40,所以说此时arr不是首元素地址,而是整个数组,4*10=40 

再来:第二个例外:看看如下代码:

int a[3] = { 0 };printf("%p\n", &a);printf("%p\n", a);printf("%p\n", &a+1);printf("%p\n", a+1);

可以看出&a与a是不一样的,&a+1,跳过了整个数组的大小,数组大小刚刚3*4=12,a+1只跳过一个元素大小。 

2.2下面我们来探讨二维数组的各个名字表示什么


int a[3][4]={0};
a[0]//第一行数组的首地址
&a[0]//第一行数组的地址

我们验证一下:

int  arr[3][4] = { {1,2,3},{4,5} };printf("arr[0]=%p\n", arr[0]);printf("&arr[0]=%p\n", &arr[0]);printf("arr[0]+1=%p\n", arr[0]+1);printf("&arr[0]+1=%p\n", &arr[0]+1);

运行结果如下:

可以看出arr[0]与&arr[0]与一维数组很像,arr[0]就是第一行数组的首地址,就相当于一维数组的数组名一样,加1只跳过一个元素,&arr[0]就是第一行数组的地址,就相当于一维数组的数组名加&一样,加一跳过第一行的所有元素,刚好是+16=4*4 

二维数组的首元素地址是什么呢?

二维数组的首元素地址不是第一行第一列元素的地址,而是第一行元素的地址,即相当于把二维数组变成一维数组,把一维数组看成二维数组的元素,即第一行的所有元素就是二维数组的第一个元素,

验证:

int arr[3][5] = { 0 };printf("%p\n", arr);printf("%p\n", &arr[0][0]);printf("%p\n", arr+1);printf("%p\n", &arr[0][0]+1);

arr+1跳过20个字节,说明跳过了4*5即第一行的所有元素, 

总结:二维数组首元素是第一行的元素的地址,与上面&a[0]一样。

*arr表示的是什么呢 ?(arr是二维数组)

我们前面知道arr是二维数组中第一行元素的1地址,解引用*arr就得到了第一行的所有元素,就相当于得到了第一行的数组名,也就相当于得到了第一行的首元素地址------即相当于arr[0].

如果理解起来有点绕,再举下面的例子,实在不行请背下吧!!!!!

我们先看一维数组

所以总而言之:

          *arr 相当于 arr[0] 这个也相当于 第一行数组的 首地址,但此时类型发生了变化,这相当于是一个指向 Int 类型的指针,所以+1后的跨度是 4 个字节,*arr + 1 就指向了第一行的第二个元素的地址

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

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

相关文章

前端24春招求职-延毕厦门某渣硕的春招0offer之旅

1 个人背景&#xff1a; 里扣刷了几十道题&#xff0c;前端开发&#xff0c;延毕半年&#xff0c;今年春季毕业的双非渣硕计算机&#xff0c;本科嵌入式&#xff0c;现在转码找工作.......前端开发&#xff0c;做过一个demo&#xff0c;现在正在补一个项目后台管理系统&#xf…

【小白专用24.5.30已验证】Composer安装php框架thinkPHP6的安装教程

一、框架介绍 1、框架简介和版本选择 Thinkphp是一种基于php的开源web应用程序开发框架ThinkPHP框架&#xff0c;是免费开源的、轻量级的、简单快速且敏捷的php框架。你可以免费使用TP框架&#xff0c;甚至可以将你的项目商用&#xff1b; ThinkPHP8.0 是目前框架正式版的最新版…

全球高端奢侈瑜伽服市场霸主Lululemon在美股的股价还有巨大的上涨空间

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 一、Lululemon公司介绍 1.1、创立与起源&#xff1a; Lululemon(LULU)由Chip Wilson于1998年在加拿大温哥华创立。1.2、产品与市场定位&#xff1a; Lululemon起初以瑜伽裤起家&#xff0c;现已发展成为涵盖瑜伽、跑步、训…

越来越多企业选择开源批发订货系统

在当今竞争激烈的市场环境中&#xff0c;越来越多的企业选择开源批发订货系统来提高运营效率、降低成本并实现业务的数字化转型。以下是开源批发订货系统的四大优势及其重要功能&#xff1a; 首先&#xff0c;开源批发订货系统具有高度的灵活性和定制性。由于其源代码开放&…

打造高效上传体验:基于Kotlin的Android快速上传框架

1. 引言 在Android开发中&#xff0c;文件上传操作常常面临各种挑战&#xff0c;为此我开源了一个高效、易用的快速上传框架&#xff0c;助力开发者轻松实现文件上传功能。 GitHub项目地址: 点我 2. 框架特点概述 纯Kotlin编写&#xff1a;简洁、现代的编程语言。MVVM架构&a…

提升船舶安全性与效率:隔离驱动芯片的应用

随着科技的不断发展&#xff0c;船舶行业也在不断迎来新的技术革新&#xff0c;其中隔离驱动芯片作为一种关键的电子元件&#xff0c;在船舶领域发挥着重要作用。本文将深入探讨隔离驱动芯片在船舶领域的应用及其技术特点。 隔离驱动芯片提升船舶系统安全性 船舶作为大型交通工…

C盘文件被格式化了,要怎么恢复?

C盘通常是操作系统(如Windows)的默认安装目录。它包含了操作系统的核心文件、驱动程序及系统所需的各种支持文件。这些文件对于计算机的正常运行至关重要。但在使用的过程中&#xff0c;有时可能会因为各种原因导致C盘被格式化&#xff0c;从而丢失了这些重要文件。这无疑是一个…

模型构建器之迭代器

上一篇我们介绍了模型构建器的基础&#xff0c;将一个工作流串联起来&#xff0c;然后做成模型工具。今天我们介绍模型构建器的第二个重要功能——迭代&#xff0c;也就是程序中的循环。 先来看一个例子。要给数据库中所有要素类添加一个相同的字段&#xff0c;该怎么做&#…

语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(二)音频数据预处理及去噪算法+Python源码应用

前言 深度学习技术在当今技术市场上面尚有余力和开发空间的&#xff0c;主流落地领域主要有&#xff1a;视觉&#xff0c;听觉&#xff0c;AIGC这三大板块。 目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相…

2024年5月架构试题

2024年5月份架构师考试真题完整版 截至2024-5-28 19:24:14已全部收录完成 共75道选择题&#xff0c;5道案例题&#xff0c;4道论文题。题目顺序不分先后。 全网最全的2024年5月份架构师考试真题回忆版&#xff0c;包含答案和解析。 选择题 计算机基础 操作系统调度算法 选先来先…

Debian常用指令指南:高效管理你的Linux系统

Debian作为Linux发行版中的佼佼者&#xff0c;以其稳定性和安全性而闻名。掌握Debian的常用指令对于系统管理员和开发人员来说至关重要。本文将介绍一系列Debian系统中的常用指令&#xff0c;帮助你高效地管理和维护你的系统。喜欢的话记得一键三连哦&#xff0c;方便找到它。 …

【Linux基础】Linux了解、安装centos虚拟机

【Linux基础】Linux了解、安装centos虚拟机 文章目录 【Linux基础】Linux了解、安装centos虚拟机1、什么是Linux2、Linux安装2.1、使用VMware安装Linux centos72.2、启动虚拟机安装 1、什么是Linux Linux是一套免费使用和自由传播的操作系统。说到操作系统&#xff0c;大家比较…

vscode 远程连接出现问题

终端太小了&#xff0c; 因为终端中有换行符&#xff0c;如果 终端太小会出现问题

Amis源码 embed渲染方法解析(json结构渲染原理):

js sdk中的渲染函数embed使用方式如下&#xff1a; const amis amisRequire("amis/embed"); const amisScoped amis.embed( self.$refs["mnode"],amisJSON, {}, amisEnv); //env会有默认值&#xff0c;默认值与传来的参数进行合并&#xff08;{默认值…

TiDB-从0到1-部署篇

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇 一、TiUP TiUP是TiDB4.0版本引入的集群运维工具&#xff0c;通过TiUP可以进行TiDB的日常运维工作&#xff0c;包括部署、启动、关闭、销毁、弹性扩缩容…

Nginx 实战-01-nginx ubuntu(windows WSL2) 安装笔记

前言 大家好&#xff0c;我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的&#xff0c;可以参考我的另一个项目&#xff1a; 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …

23种软件设计模式——工厂模式

工厂模式 工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一&#xff0c;它提供了一种创建对象的方式&#xff0c;使得创建对象的过程与使用对象的过程分离。 工厂模式提供了一种创建对象的方式&#xff0c;而无需指定要创建的具体类。 通过使…

关于linux查询free内存消耗命令

1、查询docker的镜像消耗free总和 docker stats --no-stream --format "table {{.Container}}\t{{.Name}}\t{{.MemUsage}}" | awk NR1 { print; next } {split($3, a, "/");mem a[1];if (mem ~ /MiB/) {mem_mb substr(mem, 1, length(mem)-3);} else…

身份认证与口令攻击

身份认证与口令攻击 身份认证身份认证的五种方式口令认证静态口令动态口令(一次性口令)动态口令分类 密码学认证一次性口令认证S/KEY协议改进的S/KEY协议 其于共享密钥的认证 口令行为规律和口令猜测口令规律口令猜测 口令破解操作系统口令破解Windows密码存储机制Windows密码破…

二分查找与模板

二分查找也称折半查找&#xff08;Binary Search&#xff09;&#xff0c;它是一种效率较高的查找方法。但是&#xff0c;折半查找要求线性表必须采用顺序存储结构&#xff0c;而且表中元素按关键字有序排列 模板如下 bool check(int x) // 检查x是否满足某种性质//模板一&am…