数组是C语言中一种基本的数据结构,它将多个相同类型的元素存储在连续的内存位置中。
定义数组的格式为 类型 变量名[数组长度] = {值1, 值2, 值3, ...};,例如:
int array[3] = {1, 2, 3}; // 定义一个数组,包含 3 个 int 值
digraph {
node [shape=plaintext, fontcolor=red, fontsize=18];
"数组:" [color=white];
node [shape=record, fontcolor=black, fontsize=14, width=4.75, fixedsize=true];
values [label="<f0> 1 | <f1> 2 | <f2> 3", color=blue, fillcolor=lightblue, style=filled];
{ rank=same; "数组:"; values }
edge [color=blue];
}
int 是数组元素的类型
array 是数组的变量名,它的类型是 int[3]
3 是数组的长度,数组创建后,长度固定不能改变
{1, 2, 3} 是数组元素的初始值
通过 数组名[索引] 的方式可以访问数组的元素,索引从 0 开始。
首个元素的索引是 0
末尾元素的索引是 N-1,其中 N 为数组的长度
注意,不能越界访问超出数组范围的位置,例如对于数组 int arrry[5],可以访问 array[0] 到 array[4],不能访问 array[5]。
digraph {
node [shape=plaintext, fontcolor=red, fontsize=18];
"数组:" -> "索引:" [color=white];
node [shape=record, fontcolor=black, fontsize=14, width=4.75, fixedsize=true];
values [label="<f0> 1 | <f1> 2 | <f2> 3", color=blue, fillcolor=lightblue, style=filled];
indices [label="0 | 1 | 2 ", color=white];
{ rank=same; "数组:"; values }
{ rank=same; "索引:"; indices }
edge [color=blue];
}
#include <stdio.h>
int main(void)
{
int array[5] = {1, 2, 3, 4, 5}; // 定义一个数组,包含 5 个 int 值
printf("%d\n", array[0]); // 查看索引 0 处的元素
printf("%d\n", array[1]); // 查看索引 1 处的元素
printf("%d\n", array[2]); // 查看索引 2 处的元素
printf("%d\n", array[3]); // 查看索引 3 处的元素
printf("%d\n", array[4]); // 查看索引 4 处的元素
array[0] = 10; // 修改索引 0 处的元素
array[1] = 20; // 修改索引 1 处的元素
array[2] = 30; // 修改索引 2 处的元素
array[3] = 40; // 修改索引 3 处的元素
array[4] = 50; // 修改索引 4 处的元素
printf("%d\n", array[0]); // 查看索引 0 处的元素
printf("%d\n", array[1]); // 查看索引 1 处的元素
printf("%d\n", array[2]); // 查看索引 2 处的元素
printf("%d\n", array[3]); // 查看索引 3 处的元素
printf("%d\n", array[4]); // 查看索引 4 处的元素
return 0;
}
说明:
这段代码首先创建了长度为 5 的数组,元素的值依次为 1,2,3,4,5
然后依次通过索引 0,1,2,3,4 查看所有元素的值
最后修改元素的值并查看
运行结果:
1
2
3
4
5
10
20
30
40
50
数组名可以隐式转换为指针,值为第一个元素的内存地址;另一方面,指针也可以像数组一样被索引。
例如:
int array[3] = {1, 2, 3}; // 定义一个数组,包含 3 个 int 值
int* ptr = array; // array 隐式转换为 int*,然后赋值给 ptr
printf("%d %d %d\n", *ptr, *(ptr + 1), *(ptr + 2)); // 打印 "1 2 3"
printf("%d %d %d\n", ptr[0], ptr[1], ptr[2]); // 打印 "1 2 3"
这个示例中,array 的类型是 int[3],将其赋值给 ptr 时,类型隐式转换为 int*,隐式转换后的值为第一个元素的内存地址。
因此 ptr 指向的地址就是数组 array 第一个元素的地址,*ptr 即该元素的值。
相应的 ptr + 1 和 ptr +2 是第二、三个元素的地址,*(ptr + 1) 和 *(ptr +2) 是第二、三个元素的值。
指针也可以像数组一样被索引,因此 ptr[0],ptr[1],ptr[2] 也可以依次访问第一、二、三个元素。
定义数组时可以省略部分元素的值,这些值会被自动设为 0。
对于 int 等类型,省略的元素值为 0
对于 float 等类型,省略的元素值为 0.0
对于指针类型,省略的元素值为 NULL
例如:
#include <stdio.h>
int main(void)
{
int array[5] = {1, 2}; // 省略的元素值自动设为 0
for (int i = 0; i < 5; i += 1)
{
printf("%d\n", array[i]); // 查看索引 i 处的元素
}
return 0;
}
说明:
定义数组 array 时长度为 5 而只设定了 2 个值,缺少的后 3 个值自动设为 0
运行结果:
1
2
0
0
0
定义数组时可以省略长度,写作 类型 变量名[] = {值1, 值2, 值3, ...};,编译器能够根据初始值列表中的值的个数自动判断数组长度。
示例:
#include <stdio.h>
int main(void)
{
int array[] = {1, 2, 3, 4, 5}; // 编译器根据值的个数自动判断数组长度为 5
for (int i = 0; i < 5; i += 1)
{
printf("%d\n", array[i]); // 查看索引 i 处的元素
}
return 0;
}
说明:
int array[] = {1, 2, 3, 4, 5}; 没有指定数组长度
编译器根据值的个数自动判断数组长度为 5,array 的类型为 int[5]
运行结果:
1
2
3
4
5
多维数组就是数组的数组,也就是数组的元素也是数组。例如:
#include <stdio.h>
int main(void)
{
int array[2][3] = {
{1, 2, 3},
{4, 5, 6},
};
for (int row = 0; row < 2; row += 1)
{
for (int col = 0; col < 3; col +=1)
{
printf("%d, ", array[row][col]);
}
printf("\n");
}
return 0;
}
说明:
int array[2][3] 是一个二维数组,array 的类型是 int[2][3],外层数组长度为 2,内层数组长度为 3
digraph {
node [shape=plaintext, fontcolor=red, fontsize=18];
"外层索引:" -> "内层索引:" -> "数组元素:" [color=white];
node [shape=record, fontcolor=black, fontsize=14, width=4.75, fixedsize=true];
values [label="<f0> 1 | <f1> 2 | <f2> 3 | <f3> 4 | <f4> 5 | <f5> 6", color=blue, fillcolor=lightblue, style=filled];
indices0 [label="0 | 0 | 0 | 1 | 1 | 1", color=white];
indices1 [label="0 | 1 | 2 | 0 | 1 | 2", color=white];
{ rank=same; "数组元素:"; values }
{ rank=same; "内层索引:"; indices1 }
{ rank=same; "外层索引:"; indices0 }
edge [color=blue];
}
运行结果:
1, 2, 3,
4, 5, 6,
定义多维数组时,只有 最外层的长度可以省略。例如:
// 合法,最外层的长度自动推断为 2
int array1[][3] = {
{1, 2, 3},
{4, 5, 6},
};
// 合法,最外层的长度自动推断为 2
int array2[][3] = {
{1, 2, 3},
{4, 5}, // 省略一个元素,实际为 {4, 5, 0}
};
// 非法,无法推断内层数组长度
int array3[2][] = {
{1, 2, 3},
{4, 5},
};
// 非法,虽然看起来可以推断内层长度为 3,但是语法禁止
int array4[2][] = {
{1, 2, 3},
{4, 5, 6},
};
说明:
array1 和 array2 省略了最外层的长度,可以自动推导为 2
内层数组长度为 3,{4, 5} 省略了一个元素,实际为 {4, 5, 0}
array3 和 array4 省略了内层的长度,不合法
array4 虽然看起来可以推断内层长度为 3,但是语法禁止