C语言数组详解

一维数组

创建和初始化

数组就是一组相同元素的集合。

他的创建:

char arr[10];
int arr1[5];

数组创建中 [] 里不能是变量,但是在c99标准之后就可以了被称为变长数组,但是不常用,而且变长数组不能初始化。

初始化:

//数组的初始化
int main()
{int arr[10] = { 1,2,3,4,5 };//不完全初始化,剩下的都是0int arr1[] = { 1,2,3,4 };int arr2[10] = { 0 };int arr3[] = { 0 };//这两种是不一样的初始化,arr2是十个元素,arr3是一个
}

创建数组的时候,如果不想指定 [] 的大小,就得初始化,数组的元素个数由初始化内容确认,例如:arr1,他的元素个数就是四个。

数组 arr 属于不完全初始化,但是他的元素个数还是10个,只不过剩下的初始化为0了。

arr2 和 arr3 要区分,他们的元素个数是不一样的。

一维数组的使用

//一维数组的使用
int main()
{int arr[10];int sz = sizeof(arr) / sizeof(arr[0]);printf("%d\n", sz);for (int i = 0; i < sz ; i++){arr[i] = i;}	for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}
}

这个代码第一个循环我们可以自己初始化数组里的内容,第二个循环输出数组。我们用  sizeof(arr) / sizeof(arr[0]  可以来计算数组里有多少个元素。

总结:1.数组里的元素个数可以计算。

            2.数组使用下标来访问,下标从0开始。

一维数组在内存中的存储

//一维数组在内存中的存储
int main()
{int arr[10];int sz = sizeof(arr) / sizeof(arr[0]);//printf("%d\n", sz);for (int i = 0; i < sz ; i++){arr[i] = i;}for (int i = 0; i < sz; i++){printf("%p\n", &arr[i]);}
}//四个字节的存储因为是int类型   连续存储  随下标的增长地址从低到高

我们可以看到一维数组在内存中是连续存储的,而且每个地址都差四个,因为数组类型是 int ,int类型是四个字节的存储,每个字节都有一个地址,所以差四个。而且随下标的增长地址从低到高

二维数组

创建和初始化

创建:

char arr[2][3];
int arr1[3][4];

初始化:

int main()
{//      行 列int arr[2][3] = { {1,2,3},{4,5,6} };int arr1[2][3] = { 1,2,3,4,5,6 };//编译器会自己把他们分开int arr2[2][3] = { {1,2},{3,4} };//不完全初始化int arr3[][3] = { {1,2,3 }, {4, 5, 6} };//行可以省略,列不可以。
}

其实二维数组可以理解成几个一维数组的集合。我们可以调试看看他们存储的值:

看到 arr1 确实编译器给他分开了,二维数组的不完全初始化也会补0。

二维数组的使用

//二维数组的使用
int main()
{int arr[2][3] = { 1,2,3,4,5,6 };int i = 0;for (i = 0; i < 2; i++){int j = 0;for (j = 0; j < 3; j++){printf("%d ", arr[i][j]);}}
}

二维数组在内存中的存储

//二维数组内存中的存储
int main()
{int arr[2][3] = {1,2,3,4,5,6};int i = 0;for (i = 0; i < 2; i++){int j = 0;for (j = 0; j < 3; j++){printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);//也是连续存储的,随下标的增长地址从低到高}}
}

可以看到二维数组和一维数组在内存中存储的方式一样,连续存储,差四个字节,随下标地址从低到高。

数组越界

int main()
{int arr[10];int sz = sizeof(arr) / sizeof(arr[0]);printf("数组里有%d个元素\n", sz);for (int i = 0; i < sz ; i++){arr[i] = i;}	for (int i = 0; i <= sz; i++){printf("%d ", arr[i]);}
}

我就用一维数组的代码,做了修改,让 i <= sz ,这样 i  会等于 10 ,这样就数组越界了。

超出了数组合法空间的访问,但是编译器不报错,但是不代表代码就是正确的。所以使用时自己最好检查,二维数组也会越界。

数组名的不同意义

为了探讨数组名的意义,我们看一个冒泡排序的函数:(不知道冒泡排序可以关注我,我后面会讲解

//函数错误版本:数组传参的数组名是什么,是首元素的地址。
void sort(int arr[])
{int sz = sizeof(arr) / sizeof(arr[0]);//所以怎么计算sz都等于1.因为地址都是等于四个字节的for (int i = 0; i < sz - 1; i++){for (int j = 0; j < sz - 1 - i; j++){if (arr[j] < arr[j + 1]){int tem = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tem;}}}
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };sort(arr);for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}
}

我们需要把数组的元素从大到小打印出来,我们看看这个代码的结果:

他没有完成我们的任务,为什么会这样?

这样我们打印sz 的值看看

发现 sz是1,但是我们不是让他计算数组的元素个数吗,为什么会是1呢,就是因为我们函数传参的时候传的是数组名,这里的数组名代表的是数组的首元素地址,而地址的大小永远都是 4 /  8  

个字节。

所以我们正确的样子是:

//函数正确版本:
void sort(int arr[],int sz)
{//int sz = sizeof(arr) / sizeof(arr[0]);//给他换到主函数里for (int i = 0; i < sz - 1; i++){for (int j = 0; j < sz - 1 - i; j++){if (arr[j] < arr[j + 1]){int tem = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tem;}}}
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);sort(arr,sz);for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}
}

通过这个例子我们就发现数组名是首元素地址的意义。

当然有两个例外:1 . sizeof( 数组名 ) 这里计算的计算整个数组的大小

2. &数组名,这里也是取出的整个数组的地址。

但是整个数组的地址在数字上和首元素地址相同,给他们分别加1 就可以看出区别了:

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

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

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

相关文章

STM32的IAP技术,BootLoader

来源 三种下载方式&#xff1a; 1、ICP&#xff1a;ST-Link, 2、ISP: FlyMcu, 3、IAP IAP简介 IAP技术的核心在于BootLoader程序的设计&#xff0c;这段程序预先烧录在单片机中&#xff0c;正常的APP程序可以使用BootLoader程序中的IAP功能写入&#xff0c;也可以两部分代码一…

【React】vite + react 项目,进行配置 eslint

安装与配置 eslint 1 安装 eslint babel/eslint-parser2 初始化配置 eslint3 安装 vite-plugin-eslint4 配置 vite.config.js 文件5 修改 eslint 默认配置 1 安装 eslint babel/eslint-parser npm i -D eslint babel/eslint-parser2 初始化配置 eslint npx eslint --init相关…

【python】常用函数汇总(持续更新……)

文章目录 【numpy.exp()】返回e的幂次方&#xff0c;e是一个常数为2.71828【np.dot()】矩阵相乘【np.linalg.inv()】矩阵求逆 【numpy.exp()】返回e的幂次方&#xff0c;e是一个常数为2.71828 举例&#xff1a;numpy.exp() 【np.dot()】矩阵相乘 【要点】 1、前者的列数后者…

强化基础-Java-泛型基础

什么是泛型&#xff1f; 泛型其实就参数化类型&#xff0c;也就是说这个类型类似一个变量是可变的。 为什么会有泛型&#xff1f; 在没有泛型之前&#xff0c;java中是通过Object来实现泛型的功能。但是这样做有下面两个缺陷&#xff1a; 1 获取值的时候必须进行强转 2 没有…

canvas画图,画矩形可拖拽移动,可拖拽更改尺寸大小

提示&#xff1a;canvas画图&#xff0c;画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖拽移动 文章目录 前言一、画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖拽移动总结 前言 一、画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖…

两张图片相似度匹配算法学习路线

大纲&#xff1a;​​​​​​目标跟踪基础&#xff1a;两张图片相似度算法-腾讯云开发者社区-腾讯云 (tencent.com) 目标跟踪基础&#xff1a;两张图片相似度算法 (qq.com) 一、传统方法 1.欧式距离&#xff08;用于判断是否完全相同&#xff09; [三维重建] [机器学习] 图…

DC电源模块的设计与调试技巧

BOSHIDA DC电源模块的设计与调试技巧 DC电源模块的设计与调试是电子工程师在实际项目中常常需要面对的任务。一个稳定可靠的DC电源模块对于电路的正常运行起到至关重要的作用。以下是一些设计与调试的技巧&#xff0c;帮助工程师们更好地完成任务。 第一&#xff0c;正确选择…

如何简化多个 if 的判断结构

多少算太多&#xff1f; 有些人认为数字就是一&#xff0c;你应该总是用至少一个三元运算符来代替任何单个 if 语句。我并不这样认为&#xff0c;但我想强调一些摆脱常见的 if/else 意大利面条代码的方法。 我相信很多开发人员很容易陷入 if/else 陷阱&#xff0c;不是因为其…

git的使用日常习惯规范与一些特殊操作

git的使用日常习惯规范与一些特殊操作 操作习惯规范创建本地新分支&#xff0c;推送新分支到云端仓库1.创建一个本地的login分支2.创建新分支后切换到新分支3.推送新分支到云端 git的特殊操作撤回commit&#xff08;取消提交到本地版本库的动作&#xff0c;本地工作区写的代码不…

鸿蒙开发(七)-UIAbility启动模式

鸿蒙开发(七)-启动模式 根据代码中定义,UIAbility的启动模式有以下几种&#xff1a; "launchType": {"description": "Indicates the boot mode of ability.","type": "string","enum": ["standard",…

springboot点餐平台网站

目 录 摘 要 1 前 言 2 第1章 概述 2 1.1 研究背景 3 1.2 研究目的 3 1.3 研究内容 4 第二章 开发技术介绍 5 2.1相关技术 5 2.2 Java技术 6 2.3 MySQL数据库 6 2.4 Tomcat介绍 7 2.5 Spring Boot框架 8 第三章 系统分析 9 3.1 可行性分析 9 3.1.1 技术可行性 9 3.1.2 经济可行…

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记12:DAC数模转换

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…

Django(二)-搭建第一个应用(1)

一、项目环境和结构 1、项目环境 2、项目结构 二、编写项目 1、创建模型 代码示例: import datetimefrom django.db import models from django.utils import timezone# Create your models here.class Question(models.Model):question_text models.CharField(max_length2…

golang grpc和protobuf的版本降级问题(version4 -> version3)

最后更新于2024年3月28日 10:57:52 简中没查到类似的文章。一点小事闹麻了&#xff0c;搞了一天&#xff0c;特意发出来造福大家。 所谓的版本就是下面这个东西proto.ProtoPackageIsVersion4或者proto.ProtoPackageIsVersion3&#xff1a; 目的 为了适配旧代码&#xff0c…

【Monero】Wallet RPC | Wallet CLI | 门罗币命令行查询余额、种子、地址等命令方法教程

ubuntu22.04 首先在运行daemon&#xff0c;详细安装运行教程可参考&#xff1a;The Monero daemon (monerod) ./monerodWallet CLI run ./monero-wallet-cli如果还没有钱包就根据提示创建钱包即可 输入密码 查询余额 balance查询种子 seed其他可执行命令操作&#xff1…

跳槽多次未成功,问题源自何处?

众所周知&#xff0c;2023年市场很难&#xff01;看着企业们纷纷裁员&#xff0c;甚至连内推这个后门都走不通&#xff01;哪怕有面试&#xff0c;都是屡屡碰壁&#xff0c;你想清楚问题出在哪了吗&#xff1f;&#x1f62d;“求职不得&#xff0c;夜不能寐&#xff1b;三更半夜…

GEE土地分类——基于遥感影像数据的不同作物的分类

简介 这里我们首先要更改原始代码的中的影像和研究区矢量的问题,这个为了防止我们计算的过程超限,建议先将我们的研究区影像和样本点先存在自己的assets中,然后导入到新的脚本中。然周本文就是对其进行影像进行归一化处理,然后进行样本点值提取至点,然后训练样本点,进行…

学习刷题-14

3.29 贪心算法 跳跃游戏 II 给定一个非负整数数组&#xff0c;你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 贪心的思路&#xff0c;局部最优&#xff1a;当前可移动距离尽可能多…

【4】单链表(有虚拟头节点)

【4】单链表&#xff08;有虚拟头节点&#xff09; 1、虚拟头节点2、构造方法3、node(int index) 返回索引位置的节点4、添加5、删除6、ArrayList 复杂度分析(1) 复杂度分析(2) 数组的随机访问(3) 动态数组 add(E element) 复杂度分析(4) 动态数组的缩容(5) 复杂度震荡 7、单链…

3.两数相加 - 链表

文章目录 题目简介题目解答代码&#xff1a; 题目链接 大家好&#xff0c;我是晓星航。今天为大家带来的是 两数相加 相关的讲解&#xff01;&#x1f600; 题目简介 题目解答 通过题目给的第一个示例来解析 图解如下&#xff1a; l1的2和l2的5首先相加变为7 这里相加结果为7…