数组是C语言提供的一种组织数据的结构,用于在一块连续的内存空间中存放一组数据,对外提供一个变量名表示一组数据,有时候这种数据结构会比使用多个变量要简洁方便。
数组声明
数据类型 数组名[数组长度];//只声明,不做初始化
数据类型 数组名[] = {数组元素1, 数组元素2, 数组元素3,...数组元素n};//声明并初始化
- 数组中存放的数据都是相同类型的
- 数组声明的时候如果不做初始化,必须指定数组的长度,数组长度一经确定便不能再修改
- 数组声明时如果不指定数组长度,则必须对数组进行初始化,初始化数据的个数即为数组的长度,这个长度之后也不再能修改
- 数组长度必须是整型表达式
代码示例
#include <stdio.h>
#define LENGTH 10
int main(int argc, char const *argv[])
{
int a = 3;
int i_arr[LENGTH]; //声明了一个数组i_arr,最多存放10个int类型的值
char c_arr[a]; // 声明了一个数组c_arr,最多存放3个char类型的值
short s_arr[6]; // 声明了一个数组c_arr,最多存放6个short类型的值
//声明了一个长度为3的数组d_arr,存放3个数值1.1、2.2、3.3
double d_arr[] = {1.1, 2.2, 3.3};
return 0;
}
数组访问
- 数组访问一般通过下标的方式进行
数组名[数组下标];
- 数组下标从0开始,到数组长度-1
- 数组在内存中的结构如下,比如有一个名为a的数组,长度为4,各元素分布及访问格式如下
a[0] | a[1] | a[2] | a[3] | a[4] |
---|
- 如果访问的数组下标大于了数组长度-1,那么编译时会报错,数组下标越界
代码示例
#include <stdio.h>
#define LENGTH 10
int main(int argc, char const *argv[])
{
int a = 3;
int i_arr[LENGTH]; //声明了一个数组i_arr,最多存放10个int类型的值
char c_arr[a]; // 声明了一个数组c_arr,最多存放3个char类型的值
//声明了一个长度为3的数组d_arr,存放3个数值1.1、2.2、3.3
double d_arr[] = {1.1, 2.2, 3.3};
for(int i = 0; i < LENGTH; i++){
i_arr[i] = i;//通过下标赋值数组元素
}
c_arr[0] = 'h';
c_arr[1] = 'i';
c_arr[2] = 'e';
d_arr[2] = i_arr[2]; //通过i_arr[下标]方式访问数组元素值
for(int i = 0; i < LENGTH; i++){
printf("i_arr[%d] = %d ", i, i_arr[i]);//通过i_arr[下标]方式访问数组元素值
}
printf("\n");
for(int i = 0; i < 3; i++){
printf("c_arr[%d] = %c ", i, c_arr[i]);
}
printf("\n");
for(int i = 0; i < 3; i++){
printf("d_arr[%d] = %f ", i, d_arr[i]);
}
printf("\n");
// d_arr[3] = 4.4;//编译会报错,访问的下标超过了数组的长度
return 0;
}
运行结果
i_arr[0] = 0 i_arr[1] = 1 i_arr[2] = 2 i_arr[3] = 3 i_arr[4] = 4 i_arr[5] = 5 i_arr[6] = 6 i_arr[7] = 7 i_arr[8] = 8 i_arr[9] = 9
c_arr[0] = h c_arr[1] = i c_arr[2] = e
d_arr[0] = 1.100000 d_arr[1] = 2.200000 d_arr[2] = 2.000000
字符串与字符数组
字符串
- 用双引号括起来的字符串
- 如果想要在字符串中包含双引号要用"
- 字符串本质是字符数组
- 当将字符串赋值给字符数组时,字符数组会在字符串末尾存放\0,以示字符串结束
- 因此字符串长度要比字符串实际存储长度小1
//比如hello字符串
char c_arr[] = "hello";
//c_arr中存放的是hello\0
- 当字符数组结尾以\0结束时,可以使用%s打印字符串
- 标准头文件<string.h>中声明了一些对字符串操作的函数
代码示例
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char c_arr[] = "hello";
for(int i = 0; i < 6; i++){
printf("c_arr[%d] = %c ", i, c_arr[i]);
}
printf("\n");
//当字符数组结尾以\0结束时,可以使用%s打印字符串
printf("c_arr is a string %s\n", c_arr);
//string中提供的字符串操作方法,可以返回字符串长度
printf("The length of string is %lu\n", strlen(c_arr));
c_arr[5] = 't';//可以赋值,说明数组长度为6比字符串长度大1
//当字符数组结尾不以\0结束时,可以使用%s打印字符串可能末尾会有乱码,因为找不到\0
printf("c_arr is a string %s\n", c_arr);
return 0;
}
运行结果
c_arr[0] = h c_arr[1] = e c_arr[2] = l c_arr[3] = l c_arr[4] = o c_arr[5] =
c_arr is a string hello
The length of string is 5
c_arr is a string hello�[��
多维数组
多维数组本质还是一个数组,数组元素由某一基础数据类型变成了数组。
多维数组的组织数据方式类似矩阵。
多维数组的声明
- 以二维数组为例
数据类型 数组名[数组元素个数][存放的数组长度];
数据类型 数组名[][存放的数组长度] = {{data1, ..., datan}, {data1, ...datan},....}
- 其中数组元素个数同一维数组,是可以省略的
- 省略后需要对数组声明时进行初始化,确定数组长度
- 作为数组元素的数组长度是不可以省略的
代码示例
#include <stdio.h>
int main(int argc, char const *argv[])
{
//一个数组,包含3个元素,每个元素都是一个3元数组
//1 2 3
//4 5 6
//7 8 9
int dem_arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
//声明一个有2个元素,每个元素都是一个有2个元素的数组
char dem_carr[2][2];
return 0;
}
多维数组使用
也是通过下标来进行访问和使用
- 因为有多层嵌套,以二维数组为例,要访问某个数据元素,需要两个下标来确定
- 比如a[2][2],表示访问二维数组a中的第3个数组的第3个值
a[0][0] | a[0][1] | a[0][2] | a[0][3] |
---|---|---|---|
a[1][0] | a[1][1] | a[1][2] | a[1][3] |
a[2][0] | a[2][1] | a[2][2] | a[2][3] |
a[3][0] | a[3][1] | a[3][2] | a[3][3] |
- 遍历多维数组时也经常会用到多层嵌套循环遍历
代码示例
#include <stdio.h>
int main(int argc, char const *argv[])
{
int dem_arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
char dem_carr[2][2];
dem_arr[2][2] = 10; //通过下标访问多维数组元素
printf("dem_arr[2][2] = %d\n", dem_arr[2][2]);
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
dem_carr[i][j] = '0' + i + j; //整型数字转字符,存ASCII码
printf("%c ", dem_carr[i][j]);
}
printf("\n");//每个数组元素单独一行
}
return 0;
}
运行结果:
dem_arr[2][2] = 10
0 1
1 2