【C语言】自定义数据类型-数组

一、数组的基本概念

引言: 假设我们要存放一个班55个同学的成绩,并且规定这些成绩都是整数,那我们可以写出以下代码:

int grade1 = 99;
int grade2 = 98;
int grade = 97;
......

我们可以发现,假设我们这样一个一个定义,代码的行数十分的冗余,有着许多的重复语句。那么我们是否有那么一个东西可以像个箱子,把这些数据(成绩)存起来呢?当然是有的,那就是数组

数组是什么?
数组是一种基本的数据结构,用于存储相同类型的多个元素(int char float 等等)。同时数组将相同类型的多个元素存储在一个连续的内存块中。数组中的每个元素都可以通过索引来访问


二、数组的创建

1. 一维数组

※一维数组的创建语法

type arrayName[arraySize];
  • type 数组
  • arrayName 数组名
  • arraySize 数字数据个数
  • [ ] 下标引用操作符

在C语言中,我们可以这样定义一个一维数组

int grade[55];

如果我们在一开始可以定义数组的大小,编译器则会根据我们输入的值,计算数组的大小,比如下面这样写

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

此时grade数组的大小为 5 * 4 个字节

我们定义了一个整形、名为grade、长度为55的一维数组。

※一维数组元素的初始化

数组的初始化有三种情况:完全初始化、不完全初始化和错误初始化

//完全初始化
int arr[5] = {1,2,3,4,5};

//不完全初始化
int arr2[6] = {1}; //第一个元素初始化为1,剩余的元素默认初始化为0

//错误的初始化 - 初始化项太多
int arr3[3] = {1, 2, 3, 4};

※一维数组元素的访问

下面我们可以通过索引(或称下标)对数组中的内容进行访问与修改
注意:C语言中数组的第一个元素的下标为0,也就是说,C语言中数组的下标是从0开始的,而最后一个的下标是arraySize - 1

grade[0] = 99; //将数组第一个值赋值为99
grade[1] = 98;//将数组第二个值赋值为98
grade[2] = 97;//将数组三个值赋值为97
grade[4] = 96;//将数组第五个值赋值为96

※一维数组元素的内存储存

我们上面说过数组在内存中是连续存放的,所以我们可以简单的画出数组在内存中的存放结构图。
在这里插入图片描述
我们可以在VS上证明数组在内存是连续的空间,在VS输入以下代码:

printf("%p\n",&grade[0]);
printf("%p\n",&grade[1]);
printf("%p\n",&grade[2]);
printf("%p\n",&grade[4]);

在这里插入图片描述
四个元素的地址依次为:
000000DB76EFF920
000000DB76EFF924
000000DB76EFF928
000000DB76EFF930
我们知道,int类型的大小为4个字节,同时我们可以观察,一、二、三数据之间相差的值正是四个字节,而第四个数据的地址与第三个数据的地址的值相差8个字节,所以我们可以看出,数组在内存中确实是连续存放的一段数据。


2. 二维数组

※二位数组的创建语法

type arrayName[rows][columns];
  • type 二维数组的数据类型
  • arrayName 二位数组的数组名
  • rows 二维数组的行数
  • columns 二维数组的列数

在C语言中,我们可以这样定义一个二维数组

int grade[3][4];

我们定义了一个整形、名为grade、行为3、列为4的二维数组。

与一维数组的不同的是,我们定义二维数组的时候,我们可以不写行数,但是我们必须声明列数,编译器会根据列数来划分数据,例如:

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

※一维数组元素的初始化

//未完全初始化
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, 1 3,4,5,6,7};

//按照行初始化
int arr4[3][5] = {{1,2},{3,4},{5,6}};

※二维数组元素的访问

下面我们可以通过索引(或称下标)对数组中的内容进行访问与修改
注意:C语言中二维数组的第一个元素的下标为[0][0]

grade[0][0] = 99; //将数组第一行第一列的值赋值为99
grade[1][0] = 98;//将数组第二行第一列的值赋值为99
grade[2][0] = 97;//将数组第三行第一列的值赋值为99

※二维数组元素的内存储存

二维数组在内存中也是连续存放的,即便它叫二维数组,同样的,我们可以在VS中输入以下代码:

printf("%p\n",&grade[0][0]);
printf("%p\n",&grade[1][0]);
printf("%p\n",&grade[2][0]);

我们可以得到以下结果
在这里插入图片描述
000000741CB7F7C8
000000741CB7F7D8
000000741CB7F7E8

我们知道,int类型的大小为4个字节,所以二维数组一行有4个数据,十二个字节,同时我们可以观察,一、二、三数据之间相差的值正是十二个字节,我们可以看出,二维数组在内存中确实是连续存放的一段数据。


3. C99中的变长数组

※变长数组是是什么?
C99引入的变长数组(Variable-Length Array,简称VLA)是一种在运行时确定大小的数组。这意味着你可以在函数内部或者任何代码块中声明一个数组,其大小由运行时的变量值决定。这对于需要动态数组大小的情况非常有用。变长数组不像数组那样子,在程序中就已经用常量或者常量表达式写死了,变长数组可以
※变长数组的语法

type arrayName[n];

  • type 数组数据类型
  • arrayName 数组名
  • n 未规定的数组长度

我们可以在程序中设置n的值

VLA的特点

  • 运行时大小: VLA的大小可以在运行时确定,这使得它们非常适合于需要动态数组大小的场景。
  • 栈分配: VLA通常在栈上分配,这意味着它们的大小受到栈空间的限制。
  • 自动存储期: VLA的生命周期与声明它们的代码块相同,它们在代码块结束时自动释放。

变长数组的实现
因为VS编译器不支持变长数组,所以我们使用GCC编译器在devC++中演示

#include <stdio.h>

int main(){
	int n;
	scanf("%d",&n);
	
	int arr[n];
	printf("创建了长度为%d的整形数组\n", n);
	
	int i = 0;
	for(i = 0; i < n; i++){
		arr[i] = i + 1;
	}
	
	for(i = 0; i < n; i++){
		printf("%d\n",arr[i]);
	}
	
	return 0;
} 

结果如下:
在这里插入图片描述

变长数组的注意事项

  • VLA的大小必须是一个在运行时已知的正整数。
  • VLA的大小不能是负数或零。
  • VLA通常在栈上分配,因此它们的大小受到栈空间大小的限制,这可能限制了它们的最大大小。

除去变长数组,我们也可以通过内存函数malloc,realloc等创建或修改大小可选择的数组


三、数组大小与元素个数的计算

计算一个数组的大小我们可以通过sizeof函数计算数组的大小

#include <stdio.h>
int main(){
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%zd\n", sizeof(arr));//求整个数组的大小
	return 0;
}

此时数组有10个整形元素,大小应该为4 * 10 个字节
在这里插入图片描述
计算一个数组的元素个数我们可以通过sizeof函数计算,将数组的大小除于一个元素的大小就会得到元素个数,如下

#include <stdio.h>
int main(){
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%zd\n", sizeof(arr)/sizeof(arr[0]));//求整个数组的元素个数
	return 0;
}

结果如下
在这里插入图片描述


四、End

小博主对数组的了解就到这里辣,谢谢大家的浏览,如有错误可以在评论区指出哦,希望对正在学习C语言的友友有帮助!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值