news 2026/9/14 17:23:25

【C语言】 数组

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C语言】 数组

目录

1,数组的概念

2,数组的创建和初始化

3,数组的使用

4,数组的内存存储情况

5,sizeof 计算数组的元素个数

6,二维数组

7,二维数组的初始化和创建

8,二维数组的使用

9,二维数值在内存的存储

10,C99中的变长数组


1,数组的概念


数组是⼀组相同类型元素的集合;从这个概念中我们就可以发现2个有价值的信息:
数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
数组中存放的多个数据,类型是相同的。
数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。

2,数组的创建和初始化

(1)创建:

type arr_name[常量值];

其实就类似声明变量一样,不同之处就在于,在后面加上一个"[]",在括号里面再加上常量。

int arr [20];

我们也可以使用其他的类型来声明数组。

char str[20]; short ptr[10];

str 是 char 类型 有20 个;

ptr 是 short 类型 有10个;

(2)初始化:

再声明数组时,还需要使数组给一定的初始值,这种就称位初始化。

那给如何给数组初始化,就需要用大括号,把数据赋值对应的数组位置上。

但我们也可以不需要全部初始,因为如果有一个数值初始化了,没有被初始化的数值,会默认初始化为0.

//完全初始化 int arr[10]={1,2,3,4,5,6,7,8,9,10}; //不完全初始化 int arr[10]={ 1 };//第一个元素初始化为1 ,全部默认为0 int arr[10]={ 0 };//第一个元素初始化为0 ,全部默认为0 int arr[3]={1,2,3,4}//error 初始化超出数值的范围

3,数组的使用

(1)数组的下标

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

声明的数值不像我们想象的那样,第一个数值的下标位置不是1,而是0,最后一个的下标不是10,而是9,所以我们声明出来的数值数组量为n,最后一位的元素的下标是n-1。

在C语⾔中数组的访问提供了⼀个操作符[] ,这个操作符叫:下标引⽤操作符。
所以对应的 arr[0]==1,arr[9]==10;

(2)数组元素输入与输出

int main() { int arr[10]={0}; for(int i=0;i<10;i++) { scanf("%d",&arr[i]); } for(int i=0;i<10;i++) { printf("%d",arr[i]); } return 0; }

与声明的变量的使用方法是同一个道理,学好如何去正确小标符“[]”就可以正确使用。


4,数组的内存存储情况

该代码在x86 环境下的arr 内存情况一下:

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

如图所示:

从&i 00EFF848到&arr[9] 00EFF83C(这是以16进制),区间距离为12个字节位,也就是3个int 的位置;例外每一个arr数组的间距都是刚好4个字节位,所以说数组的各个元素之间是连续的。

为什么会故意去提一下在x86环境,和&i的地址呢?

int main() { int i = 0; int arr[10] = { 0 }; for (i = 0; i < 13; i++) { arr[i] = 0; printf("hehe\n"); } return 0; }

该代码是打印出多少个hehe?

答案是无限个,而不是13个,所以代码已经陷入死循环了。

就是因为: 从&i 00EFF848到&arr[9] 00EFF83C(这是以16进制),区间距离为12个字节位,所以&arr[12]和&i的地址是同一个,那么arr[12]和 i 也是控制同一个数值,如果arr[12]=0,那么 i 也会等于0,那么i<13依然成立,那么所以循环依然继续,所以就陷入一个死循环,当然这种情况只在x86环境,但是在x64环境依然也是会发生的,只是&i 的值与&arr[9]拉开的距离比较远而已。

这个内容在《C缺陷与陷阱》的有详细讲述。


5,sizeof 计算数组的元素个数

我们知道sizeof 可以用来计算声明类型的所占的字节大小,那么他也可以用来计算,arr 所占的字节大小并且也可以来计算出元素数量。

int main() { int arr[10]; printf("%zu ",sizeof(arr)); printf("%zu ",sizeof(arr)/sizeof(arr[0])); return 0; }

输出结果:40 10

一个sizeof 可以计算出arr 所占的内存长度,

那么两个sizeof计算后相除就可以计算出arr 的元素数量。


6,二维数组

我们上面学的是一维数组,那么一维数组和二维数组有什么区别呢?

其实区别并不大,只是多了一个中括号“[]”

int arr[3][5]; float str[4][2]; char a[3][4];


7,二维数组的初始化和创建

初始化也是一样的依然需要大括号{},但是要明确哪里要初始化就需要两个大括号{}

//不完全初始化 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}; 1 int arr6[][5] = {1,2,3,4,5,6,7}; int arr7[][5] = {{1,2}, {3,4}, {5,6}};

8,二维数组的使用

与一维数组同理,第一行第一个都是arr[0][0]。

#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[1][3]); return 0; }

输出结果为:5


二维数组的输入与输出

其实我们只要能够按照⼀定的规律产⽣所有的⾏和列的数字就⾏;以上⼀段代码中的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}; //输⼊ for(int i = 0; i < 3; i++) //⾏号 { for(int j = 0; j < 5; j++) //列号 { scanf("%d", &arr[i][j]); //输⼊ } } //输出 for(int i = 0; i < 3; i++) //⾏号 { for(int j = 0; j < 5; j++) //列号 { printf("%d ", arr[i][j]); //输出 } printf("\n"); } return 0; }

9,二维数值在内存的存储

代码展示:

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

不难发现arr 各个元素的元素距离也依然都是相同的4个字节位(注意int声明),所以他们的内存空间也是一个有顺序的的排列

int main() { int arr[3][4] = { 0,1,2,3,1,2,3,4,2,3,4,5 }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("&arr[%d][%d] = %d\n", i, j, arr[i][j]); } } for (int i = 0; i < 12; i++) printf("%d ", arr[0][i]); return 0; }

两种输出方式都是可以的。


10,C99中的变长数组

通常在声明数组的时候是不可以在括号内添加变量的,不然直接就报错了。

但是有了C99种给了一个变长数组的特性,允许我们可以自行更改数组的长度。

在逻辑上 i 就可以随意更改arr 的数组元素数量,编译器没法事先确定,只有运⾏时才能知道 i是多少。

#include <stdio.h> int main() { int n = 0; scanf("%d", &n);//根据输⼊数值确定数组的⼤⼩ int arr[n]; int i = 0; for (i = 0; i < n; i++) { scanf("%d", &arr[i]); } for (i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; }

第一次输出结果:

第二次输出结果:


感谢观看!

悠仁さん

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 17:22:31

供配电实训仿真软件:倒闸操作与故障处理全流程解析

干电气培训这些年&#xff0c;我见过太多学员第一次面对高压柜时的表情——手放在断路器分闸按钮上&#xff0c;迟迟不敢按下去。不是不知道步骤&#xff0c;而是怕按错了出大事。这种怕是对的&#xff0c;10kV开关柜一旦带负荷拉隔离开关&#xff0c;电弧瞬间就能把人灼伤&…

作者头像 李华
网站建设 2026/9/14 17:19:13

C++序列输出题全攻略:从读题到OJ提交的完整避坑指南

1. 一道短得不像话的题&#xff0c;凭什么让我交了三版才过东华OJ的基础题里有一类题属于“看着简单、做着崩溃”&#xff0c;第50题“按要求输出序列”就是典型。题面可能短到只有一句话&#xff0c;给一个整数N&#xff0c;让你按某种规则输出一串数。很多人的第一反应是&…

作者头像 李华
网站建设 2026/9/14 17:17:56

商丘做建设网站的公司3个最佳实践解决网站被黑

商丘做建设网站的公司3个最佳实践解决网站被黑 网站被黑挂马,后台密码泄露,首页瞬间变成赌博链接,这种绝望感每个运维都懂。在商丘本地,很多中小企业找 商丘做建设网站的公司 时,只盯着价格,却忽略了安全架构,结果就是养虎为患。面对这种紧急状况,盲目重装系统往往治标不治本,真正的 最佳实践…

作者头像 李华
网站建设 2026/9/14 17:10:55

多无人机动态避障路径规划与MATLAB实现

1. 项目概述&#xff1a;多无人机动态避障的工程挑战去年参与某物流园区无人机集群项目时&#xff0c;我们遇到一个典型场景&#xff1a;7台物流无人机需要在3分钟内穿越布满移动障碍物的装卸区。传统RRT算法在动态环境下频繁出现路径震荡&#xff0c;最终有3台无人机因避障超时…

作者头像 李华