C语言:一维、二维数组详解

news2024/9/21 20:41:13

目录

一、数组的概念

二、一维数组创建和初始化

2.1 数组创建

2.2 数组的初始化

2.3 数组的类型

三、一维数组的使用

3.1 数组的下标

3.2 数组的输入与输出

四、⼀维数组在内存中的存储

五、sizeof计算数组元素个数

六、二维数组

6.1 二维数组的概念

6.2 二维数组的创建

6.3 二维数组的初始化

不完全初始化

 完全初始化

按照行初始化

初始化时省略行,但是不能省略列  

​6.4 二维数组的使用

⼆维数组的下标

⼆维数组的输入和输出

 6.5 ⼆维数组在内存中的存储


一、数组的概念

数组是⼀组相同类型元素的集合;从这个概念中我们就可以发现2个有价值的信息:

• 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。

• 数组中存放的多个数据,类型是相同的。

数组分为⼀维数组和多维数组,多维数组⼀般比较多见的是⼆维数组。

二、一维数组创建和初始化

2.1 数组创建

⼀维数组创建的基本语法如下:

type arr_name[常量值];

存放在数组的值被称为数组的元素,数组在创建的时候可以指定数组的大小数组的元素类型。

• type 指定的是数组中存放数据的类型,可以是: char、short、int、float 等,也可以自定义的类型

• arr_name 指的是数组名的名字,这个名字根据实际情况,起的有意义就行。

• [] 中的常量值是用来指定数组的大小的,这个数组的大小是根据实际的需求指定就行。 

比如:我们现在想存储某个班级的20⼈的数学成绩,那我们就可以创建⼀个数组,如下:

int math[20];

当然我们也可以根据需要创建其他类型和大小的数组: 

char ch[8];
double score[10];

2.2 数组的初始化

    有时候,数组在创建的时候,我们需要给定⼀些初始值值,这种就称为初始化的。 那数组如何初始化呢?数组的初始化⼀般使用大括号,将数据放在大括号中。

//完全初始化 
int arr[5] = {1,2,3,4,5};
//不完全初始化 
int arr2[6] = {1};//第⼀个元素初始化为1,剩余的元素默认初始化为0 
//错误的初始化 - 初始化项太多 
int arr3[3] = {1, 2, 3, 4};

2.3 数组的类型

     数组也是有类型的,数组算是⼀种自定义类型,去掉数组名留下的就是数组的类型。

如下: 

int arr1[10];
int arr2[12];
char ch[5];

arr1数组的类型是 int [10]

arr2数组的类型是 int[12]

ch 数组的类型是 char [5] 

三、一维数组的使用

3.1 数组的下标

      C语言规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下标就相当于数组元素的编号,如下:

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

 在C语言中数组的访问提供了⼀个操作符 [] ,这个操作符叫:下标引用操作符

     有了下标访问操作符,我们就可以轻松的访问到数组的元素了,比如我们访问下标为7的元素,我们就 可以使用 arr[7] ,想要访问下标是3的元素,就可以使⽤ arr[3] ,如下代码:

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

3.2 数组的输入与输出

    明白了数组的访问,当然我们也根据需求,自己给数组输入想要的数据,如下:

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

     接下来,如果想要访问整个数组的内容,那怎么办呢? 只要我们产生数组所有元素的下标就可以了,那我们使用for循环产生0~9的下标,接下来使用下标访问就行了。  

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

四、⼀维数组在内存中的存储

     有了前面的知识,我们其实使用数组基本没有什么障碍了,如果我们要深入了解数组,我们最好能了解⼀下数组在内存中的存储。

依次打印数组元素的地址

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

     从输出的结果我们分析,数组随着下标的增长,地址是由小到大变化的,并且我们发现每两个相邻的元素之间相差4(因为⼀个整型是4个字节),所以我们得出结论:数组在内存中是连续存放的。

五、sizeof计算数组元素个数

    在遍历数组的时候,我们经常想知道数组的元素个数,那C语⾔中有办法使用程序计算数组元素个数吗? 答案是有的,可以使用sizeof。 

    sizeof 中C语言是⼀个关键字,是可以计算类型或者变量大小的,其实 sizeof 也可以计算数组的大小。

比如:

#include <stido.h>
int main()
{
 int arr[10] = {0};
 printf("%d\n", sizeof(arr));
 return 0;
}

    这里输出的结果是40,计算的是数组所占内存空间的总大小,单位是字节。 

    我们又知道数组中所有元素的类型都是相同的,那只要计算出⼀个元素所占字节的个数,数组的元素个数就能算出来,这里我们选择第⼀个元素算大小就可以。

#include <stido.h>
int main()
{
 int arr[10] = {0};
 int sz = sizeof(arr)/sizeof(arr[0]);
 printf("%d\n", sz);
 return 0;
}

     这里的结果是:10,表示数组有10个元素,以后在代码中需要数组元素个数的地方就不用固定写了,使用上面的计算,不管数组怎么变化,计 算出的大小也就随着变化了。

六、二维数组

6.1 二维数组的概念

     前面学习的数组被称为⼀维数组,数组的元素都是内置类型的,如果我们把⼀维数组做为数组的元素,这时候就是二维数组,二维数组作为数组元素的数组被称为三维数组,二维数组以上的数组统称为多维数组。

6.2 二维数组的创建

我们如何定义⼆维数组呢?语法如下:

type arr_name[常量值1][常量值2];
例如:
int arr[3][5];
double data[2][8];

• 3表示数组有3行

• 5表示每⼀行有5个元素

• int 表示数组的每个元素是整型类型

• arr 是数组名,可以根据自己的需要指定名字

data数组意思基本⼀致。

6.3 二维数组的初始化

     在创建变量或者数组的时候,给定⼀些初始值,被称为初始化, 那⼆维数组如何初始化呢?像⼀维数组⼀样,也是使用大括号初始化的。

不完全初始化

int arr1[3][5] = {1,2};
int arr2[3][5] = {0};

 完全初始化

int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

 

按照行初始化

int arr4[3][5] = {{1,2},{3,4},{5,6}};

初始化时省略行,但是不能省略列  

int arr5[][5] = {1,2,3};
int arr6[][5] = {1,2,3,4,5,6,7};
int arr7[][5] = {{1,2}, {3,4}, {5,6}};

二维数组的下标

当我们掌握了⼆维数组的创建和初始化,那我们怎么使用⼆维数组呢?

其实⼆维数组访问也是使用下标的形式的,⼆维数组是有行和列的,只要锁定了行和列就能唯⼀锁定 数组中的⼀个元素。

C语⾔规定,⼆维数组的行是从0开始的,列也是从0开始的,如下所示:

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

     图中最右侧绿色的数字表示行号,第⼀行蓝色的数字表示列号,都是从0开始的,比如,我们说:第2行,第4列,快速就能定位出7。

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

二维数组的输入和输出

    访问⼆维数组的单个元素我们知道了,那如何访问整个⼆维数组呢?

     其实我们只要能够按照⼀定的规律产生所有的行和列的数字就行,以上⼀段代码中的arr数组为例,行的选择范围是0~2,列的取值范围是0~4,所以我们可以借助循环实现生成所有的下标。

#include <stdio.h>
int main()
{
 int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
 int i = 0;//遍历⾏ 
 //输⼊ 
 for(i=0; i<3; i++) //产⽣⾏号 
 {
 int j = 0;
 for(j=0; j<5; j++) //产⽣列号 
 {
 scanf("%d", &arr[i][j]); //输⼊数据 
 }
 }
 //输出 
 for(i=0; i<3; i++) //产⽣⾏号 
 {
 int j = 0;
 for(j=0; j<5; j++) //产⽣列号 
 {
 printf("%d ", arr[i][j]); //输出数据 
 }
 printf("\n");
 }
 return 0;
}

 6.5 二维数组在内存中的存储

     像⼀维数组⼀样,我们如果想研究⼆维数组在内存中的存储方式,我们也是可以打印出数组所有元素 的地址的,代码如下:

#include <stdio.h>
int main()
{
 int arr[3][5] = { 0 };
 int i = 0;
 int j = 0;
 for (i = 0; i < 3; i++)
 {
 for (j = 0; j < 5; j++)
 {
 printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
 }
 }
 return 0;
}

     从输出的结果来看,每一行内部的每个元素都是相邻的,地址之间相差4个字节,跨行位置处的两个元 素(如:arr[0][4]和arr[1][0])之间也是差4个字节,所以二维数组中的每个元素都是连续存放的。

如下图所示:


    本篇内容就到这里了,希望对各位有帮助,如果有错误欢迎指出。

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

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

相关文章

虚幻游戏开发 | shader性能优化

如何查看shader性能消耗 1.Alt 8切换Shader Complexity mode查看shader性能消耗 (Alt 4切换回Lit Mode正常光照模式) 2.材质蓝图里查看instructions数量&#xff08;如图中箭头所示&#xff09; 3.直接在target platform上测试是最准确的。 &#xff08;running fewer instru…

思特科技案例:北京欢乐谷光影乐园

01      在北京欢乐谷的亲子领域&#xff0c;藏着一处“面积近400平米&#xff0c;炫酷堪比魔法世界的、美轮美奂的光影空间&#xff0c;做到了“让娃来了不想走&#xff0c;一玩就是一下午”。    思特科技案例&#xff1a;北京欢乐谷光影乐园      02      作…

去抖音视频水印的软件免费推荐,精选四款实用工具助你轻松去除水印

随着抖音等短视频平台的流行&#xff0c;我们常常会遇到想要保存某些视频但不想保留水印的情况。本文将为您推荐四款去抖音视频水印的实用工具&#xff0c;帮助您轻松去除视频中的水印&#xff0c;保存清晰的内容。 工具一&#xff1a;奈斯水印助手(小程序) 推荐指数&#xf…

DMDSC学习

DMDSC学习 ​ DM 共享存储数据库集群&#xff0c;允许多个数据库实例同时访问、操作同一数据库&#xff0c;具有高可用、高性能、负载均衡等特性。DMDSC 支持故障自动切换和故障自动重加入&#xff0c;某一个数据库实例故障后&#xff0c;不会导致数据库服务无法提供。 DMDSC…

前端使用miniO上传文件

项目背景:vue2&#xff0c;前提是请先安装miniO,若安装引入时报错&#xff0c;那就是版本不对&#xff0c;通常指定版本安装即可。 页面样式&#xff1a; 前端vue页面代码&#xff1a; //<el-form>表单中:<el-form-item label"文件" prop"fileIds&q…

链表OJ题——反转一个单链表

文章目录 一、题目链接二、解题思路三、解题代码 一、题目链接 原地翻转链表 二、解题思路 原地翻转链表&#xff0c;空间复杂度为O(1)&#xff0c;时间复杂度O(n) 三、解题代码

亲测好用,吐血整理 ChatGPT 3.5/4.0 新手使用手册~ 【2024 更新】

废话不多说&#xff0c;直接分享正文~ 以下是小编为大家搜集到的最新的ChatGPT国内站&#xff0c;各有优缺点。 1、AI Plus&#xff08;稳定使用&#xff09; 推荐指数&#xff1a;⭐⭐⭐⭐⭐ yixiaai.com 该网站已经稳定运营了1年多了。2023年3月份第一批上线的网…

高速公路边坡在线监测预警系统

一、背景 近日&#xff0c;广东梅大高速发生严重塌方事故&#xff0c;造成了严重的人员伤亡和财产损失。这一事件在公众心中敲响了安全的警钟&#xff0c;再次引起了公众对于交通设施运营安全性的重点关注。 二、系统介绍 高速公路边坡在线监测预警系统通过结合北斗、5G、AI…

jstack结果提取特定线程池线程的堆栈

这里假设你已经知道如何定位java进程PID&#xff0c;以及如何执行jstack命令进行导出&#xff0c;下面仅提供相关命令&#xff0c;及示例 ps aux|grep java jstack 8229 > jstack_output.log v1版本 grep second jstack_output.log 如果此时我们想重点关注一下下面这个线程…

极简接入|七牛云 QPlayer2 播放器再升级

1877 年&#xff0c;爱迪生发明留声机&#xff0c;用锡箔筒捕捉了第一缕声波。随后&#xff0c;黑胶唱片、磁带录音机、八轨盒式磁带机、卡式磁带、激光唱片&#xff08;CD&#xff09;等相继问世。 每一次介质的变革&#xff0c;都带来了音质的提升和便捷性的增强。时光流转&a…

LLM概念梳理(一):训练流程之PT、SFT和PO

一个LLM的成功问世&#xff0c;一般分为&#xff1a;预训练 PT监督微调 SFT偏好优化 PO。 预训练&#xff08;Pre-Training&#xff09;是为了让模型学习通用知识&#xff0c;而监督微调&#xff08;Supervised Fine-Tuning&#xff09;是为了优化模型在特定任务上的表现。为了…

TypeScript学习笔记1---认识ts与js的异同、ts的所有数据类型详解

前言&#xff1a;去年做过几个vue3js的项目&#xff0c;当时考虑到时间问题&#xff0c;js更加熟悉&#xff0c;学习成本低一点&#xff0c;所以只去了解了vue3。最近这段时间补了一下ts的知识点&#xff0c;现今终于有空来码文章了&#xff0c;做个学习总结&#xff0c;方便以…

360驱动大师 v2.0.0.2040 最新免费精简单文件版

360驱动大师是一款专注于驱动安装和更新的专业软件&#xff0c;它拥有庞大的驱动库&#xff0c;能够支持数以百万计的不同类型的驱动程序。 它的设计理念是简化驱动管理和更新的过程&#xff0c;让用户能够轻松地保持系统的最新状态&#xff0c;从而获得更好的性能和稳定性。无…

Linux高编-进程的概念(1)

目录 1.ps aux 2.top 3.kill -2 进程pid // fork函数 getpid拿自己的进程号 getppid拿父进程号 fork&#xff08;&#xff09;&&fork&#xff08;&#xff09;||fork&#xff08;&#xff09; 父子进程的关系&#xff1a; 僵尸进程&#xff0c;孤儿进程 僵…

zookeeper源码分析之事务请求处理

一.参考 zookeeper启动和选举的源码分析参考之前的帖子. 二.源码 1.职责链模式. 每次经过的processor都是异步处理&#xff0c;加入当前processor的队列&#xff0c;然后新的线程从队列里面取出数据处理. PrepRequestProcessor 检查ACL权限,创建ChangeRecord. SyncRequest…

用Python更改Word文档文本的字体

更改文字字体是编辑和美化Word文档时的一项常见需求&#xff0c;使用合适的字体不仅可以提升文档的整体视觉效果&#xff0c;还能突显关键信息&#xff0c;使得内容更加突出。然而&#xff0c;手动更改每一个文字的字体既繁琐又费时。因此&#xff0c;掌握一种高效的方法来自动…

verilog当中仿真的时候赋值用=还是<=

【总结&#xff1a;<是所有数据同时变化&#xff0c;而是顺序执行。如果是左边数据的赋值都是不关联的&#xff0c;那么就可以用<&#xff0c;使所有赋值同时有效。如果有a和b都需要赋值&#xff0c;且b的值跟a有关的同时还需要一起变化&#xff0c;那么可以用】 一般情…

C++ UML 使用 doxygen 生成源码类图

一&#xff1a;安装 sudo apt install doxygensudo apt install doxygen-guisudo apt install graphviz graphviz-doc 二&#xff1a;使用 命令行输入 doxywizard&#xff0c;打开图形界面 参考&#xff1a; https://www.cnblogs.com/guohaoblog/p/15151353.html

探秘:哪些项目需要代理IP来助力?

网络爬虫&#xff1a;数据采集的秘密武器 网络爬虫是互联网世界中的“数据矿工”&#xff0c;它们在网络中不断爬行&#xff0c;采集各种有用的信息。然而&#xff0c;频繁的访问请求很容易引起目标网站的警觉&#xff0c;甚至被封禁。此时&#xff0c;代理IP就像是爬虫的“隐…

Springboot发邮件功能如何实现?详细步骤?

Springboot发邮件配置指南&#xff1f;如何集成Spring Mail发邮件&#xff1f; 无论是用户注册、密码重置还是重要通知的发送&#xff0c;邮件都是不可或缺的沟通方式。Springboot作为一个流行的Java开发框架&#xff0c;提供了简洁易用的方式来实现邮件功能。AokSend将详细探…