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

新手必看!C语言数组宝宝级讲解,看完直接懂

1. 数组的概念

1.1 基本概念

数组是一组相同类型元素的集合;那宝宝们从这个概念中我们可以可以发现两个重要的信息:

  • 宝宝们数组中存放的是1个或者多个数据,但数组元素个数不能为0
  • 宝宝们数组中存放的多个数据,类型是相同的

还有宝宝们数组分为一维数组和多维数组,二维数组是最为常见的多维数组

2. 一维数组

2.1 一维数组的创建

//一维数组创建的基本语法如下: type arr_name[常量值]; //type:数组存放数据的元素类型,可以是:char、short、int、float等,也可以自定义的类型。 //arr_name:数组名,这个名字可以自定义。 //[常量值]:宝宝们这里的常量值表示数组元素的个数,可以用来指定数组的大小。

宝宝们下面我们就来创建一些数组:

int data[10]; char ch[20];

宝宝们因为讲了数组的创建就不得不讲一下数组中有的类型了:

就拿 int data[10]; 这个数组来说: 元素类型:int 数组类型:int[10] 数组指针类型:int (*)[10]

2.2 一维数组的初始化

宝宝们在有时候在数组创建的时候我们要指定一些初始值,这个过程我们就叫它数组的初始化。
当然宝宝们,数组初始化分为完全初始化和不完全初始化,下面我就来一一介绍:

intmain(){//完全初始化:intarr1[5]={0,1,2,3,4};intarr2[]={0,1,2,3,4};//宝宝们这种也是完全初始化 编译器推断为arr2[5]//不完全初始化:intarr3[5]={0,1,2};intarr4[5]={0};//错误的初始化://int arr5[];//不能这样初始化 可以不初始化数组长度,也可以不初始化数组的内容,但是不能两个都不初始化//int arr5[5] = {0, 1, 2, 3, 4, 5};//数组越界初始化 问题:初始化列表元素数量(6个)超过了数组声明大小(5个)。return0;}

int arr5[];问题:

宝宝们这样写编译器无法确定数组的大小

int arr5[];//大小未知,编译器无法分配栈空间 int arr5[10];//明确占用10 * sizeof(int)字节

一维数组越界初始化问题:

  • 编译期:GCC/Clang会产生警告excess elements in array initializer
  • 运行期:超出的元素会被丢弃,数组实际只存储前面一些在它存储大小内的元素
int arr5[5] = {0, 1, 2, 3, 4, 5};//arr5实际只存储{0, 1, 2, 3, 4},最后的5被抛弃

2.3 一维数组的下标 | 索引

宝宝们c语言规定数组是有下标(也可以叫索引)的,数组是通过下标访问到具体元素的,下标从0开始,假设数组有个n元素,那最后一个元素的下标为n-1,下标就相当于数组元素的编号,就比如:

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

#include<stdio.h>intmain(){intarr[5]={1,2,3,4,5};printf("%d\n",arr[0]);//0printf("%d\n",arr[3]);//3return0;}

2.4 一维数组元素的输入输出

宝宝们整形一维数组是没有办法一次性输入和输出的,只能这样:

#include<stdi.h>intmain(){intarr[5]={0};for(inti=0;i<5;i++){scanf("%d",&arr[i]);}for(intj=0;j<5;j++){printf("%d ",arr[j]);}return0;}

但是宝宝们字符型一维数组不仅仅只有上面那种写法,还有这种:

#include<stdio.h>intmain(){chararr[100];scanf("%s",arr);printf("%s\n",arr);return0;}

2.5 计算一维数组元素个数

宝宝们我们计算数组元素个数的时候一般用**sizeof**

宝宝们sizeof中C语言是一个关键字,是可以计算类型或者变量大小的,但也可以用sizeof也可以计算数组的大小。

#include<stdio.h>intmain(){intarr[5]={0};printf("%d\n",sizeof(arr));//输出结果为20return0;}

宝宝们这里输出的结果是20,计算的是数组所占内存空间的总大小,数组所占内存空间的总大小 = 元素个数 × 单个元素字节数,整形元素字节数为4,所以数组所占内存空间的总大小 = 4 * 5 = 20。所以宝宝们我们要计算元素个数就要 数组所占内存空间的总大小 / 单个元素字节数,这里我们一般选择第一个元素
那宝宝们接下来就来计算出数组元素个数:

#include<stdio.h>intmain(){intarr[5]={0};intsz=sizeof(arr)/sizeof(arr[0]);printf("%d\n",sz);//5return0;}

这里的结果是5,表示数组最大存储5个元素,宝宝们。

3. 二维数组

3.1 二维数组的概念

宝宝们因为数组都是内置类型的,如果我们把一维数组做为数组元素,这时候所组成的数组就是二维数组,同理把二维数组做为数组元素就是三维数组,二维数组以上的数组通称为三维数组。

3.2 二维数组的创建

type arr_name[常量1][常量2];//表示常量1行常量2列 比如: int arr1[1][5];//表示1行5列 int arr2[3][5];//表示3行5列

二维数组中有的类型:

宝宝们我们拿 int arr2[3][5] 这个数组来说: 元素类型:int[5] 数组类型:int[3][5]

3.3 二维数组的初始化

宝宝们,二维数组的初始化也分为完全初始化和不完全初始化:

intmain(){//完全初始化:intarr1[3][5]={0,1,2,3,4,1,1,2,3,4,2,1,2,3,4};intarr2[3][5]={{0,1,2,3,4},{1,1,2,3,4},{2,1,2,3,4}};intarr3[][5]={{0,1,2,3,4},{1,1,2,3,4},{2,1,2,3,4}};//不完全初始化:intarr4[3][5]={0,1,2};intarr5[3][5]={0};intarr6[3][5]={{1,2},{3,4},{5,6}};intarr7[][5]={{1,2},{3,4},{5,6}};//错误的初始化:intarr8[3][]={{0,1,2,3,4},{1,1,2,3,4},{2,1,2,3,4}};intarr9[][]={0,1,2,3,4,5};//二维数组的初始化可以省略行但是不能省略列intarr10[3][5]={{0,1,2,3,4},{1,1,2,3,4},{2,1,2,3,4},{3,1,2,3,4}};//数组越界初始化return0;}

宝宝们我们来说一下int arr8[3][] = {{0, 1, 2, 3, 4}, {1, 1, 2, 3, 4}, {2, 1, 2, 3, 4}};错误初始化的问题:
这报错根本的问题编译器无法计算元素地址,访问arr[i][j]的地址计算公式为:base_addr + (i × 第二维长度 × sizeof(int)) + (j × sizeof(int)),如果j未知编译器无法计算行偏移,宝宝们就比如二维数组是一栋房子i代表楼层数,j代表每层的房间数,要找「2楼3号房」,必须先知道每层有多少个房间,才能算出2楼从哪里开始:2楼起点 = 入口 + (2 × 每层房间数 × 房间大小),如果每层房间数未知,根本不知道2楼从哪里开始,找不到任何房间。
那宝宝们为什么int arr[][5] = {0, 1, 2, 3, 4, 5};能够这样初始化呢?
编译器会用总元素数 ÷ 列数来推导出行数,如果是int arr[][] = {0, 1, 2, 3, 4, 5};这样没有列数就不能推导出行数,所以宝宝们这样初始化也不行。
总结:二维数组的初始化可以省略行但是不能省略列

3.4 二维数组的下标 | 索引

宝宝们二维数组访问也是使用下标(或者索引)的形式的,只要锁定了行和列就能唯一锁定数组中的一个元素,当然行和列也都是从0开始的。
就比如:

intmain(){intarr[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};printf("%d\n",arr[2][3]);//14return0;}

3.5 二维数组的输入和输出

宝宝们因为二维数组有行和列所以二维数组的输入和输出要用2个for循环

#include<stdio.h>intmain(){intarr[3][5];for(inti=0;i<3;i++)//行{for(intj=0;j<5;j++)//列{scanf("%d",&arr[i][j]);}}for(inti=0;i<3;i++)//行{for(intj=0;j<5;j++)//列{printf("%d ",arr[i][j]);}printf("\n");}return0;}

4. 数组在内存中的存储

宝宝们在了解数组在内存中的存储我们先得了解x64x86之间的关系:

  • x64:编译产生64位的程序地址是64位的,比较长
  • x86:编译产生32位的程序地址是32位的,比较短

那宝宝们我们就分别用x64x86来依次打印数组元素地址
代码如下:

#include<stdio.h>intmain(){intarr[5]={0,1,2,3,4};for(inti=0;i<10;i++){printf("&arr[%d] = %p\n",i,&arr[i]);}return0;}


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

5. 总结

上面结论这么多,那宝宝们我们现在来总结一下吧

  1. 数组的概念:数组是一组相同类型元素的集合
  2. 一维数组:
要点说明
创建type arr_name[常量值];
初始化完全/不完全初始化;[]中的常量值可省略但需有初始化列表
访问arr[i],下标从0开始
输入输出整形用循环逐个;char型可直接用%s
元素个数sizeof(arr) / sizeof(arr[0])
  1. 二维数组:
要点说明
创建type arr[行][列],本质是"一维数组的数组"
初始化行可省略,列不可省略(编译器靠列数计算地址偏移)
访问arr[i][j],行列均从0开始
输入输出必须用两层for循环
  1. 内存存储:

数组在内存中连续存放,随下标增大,地址从低到高递增,相邻元素地址差 = sizeof(元素类型)

http://www.jsqmd.com/news/807296/

相关文章:

  • AI应用配置管理实战:从环境变量到多租户架构的工程化解决方案
  • 重选,重定向,切换之间的区别
  • AMOLED屏幕像素抓取工具:原理、实现与自动化测试应用
  • 现在不学就落伍:Gemini 2.5已支持Workspace多模态事件触发(含3个即将下线的旧版API迁移清单)
  • snipkit:极速代码片段与灵感速记工具箱的设计与实践
  • CC-Switch 完整下载、安装与使用教程(Claude Code 配置 2026.5.12)
  • AI 术语通俗词典:贝叶斯估计
  • 从新手到老手:四类Ozon卖家选品工具选择指南
  • 比官方插件更硬核?深度解析 Coding Agent 爆款扩展 Superpowers
  • XTS apk install问题
  • 百度网盘直链解析工具:3分钟突破限速,实现全速下载
  • 拯救者笔记本终极控制指南:用开源工具箱完全替代官方软件
  • RE正则提取数字
  • 别急着改代码!Eclipse中‘could not be resolved’报错的5种排查思路与根治方法
  • DOM Node:深入解析与高效使用
  • 如何快速使用NeteaseCloudMusicFlac:无损音乐下载完整指南
  • OpenAI面向欧洲部分用户开放网络安全专用模型GPT-5.5-Cyber,应对AI网络威胁
  • RoboBERT:轻量级多模态机器人操作框架解析
  • 2026年高性价比的全案装修设计专业公司排名,丽江阆朗装饰第几? - mypinpai
  • 别再为Teamcenter 13安装头疼了!一份超详细的虚拟机环境搭建与验证清单(附资源下载)
  • 如何高效管理Android自动化规则:GKD订阅管理完全配置指南
  • AI增强自动化工作流:从规则驱动到意图驱动的智能决策实践
  • 免费一键去图片水印的App有哪些?免费去图片水印软件推荐,2026实测好用工具盘点
  • 5分钟快速指南:用DistroAV插件将OBS变成专业级网络视频制作系统
  • 2026年星硕辰沙盘模型多少钱?费用明细揭秘 - mypinpai
  • 知识图谱:AI的超级大脑
  • 号卡系统后台一键生图换图添加随心ai密钥教程
  • uuntu24.04.4 LTS 添加开机启动程序
  • 从RNN的“失忆症”到LSTM的“记忆宫殿”:图解三个门控单元如何拯救梯度消失
  • 小米Agent岗二面:你们 RAG 知识库上线之后,文档更新了怎么办?