08 · 数组

2026.09.27 · 🔴 难(与 Java 差异大)

声明与初始化

int a[5];                        // 5 个 int,未初始化(垃圾值)
int b[5] = {1, 2, 3, 4, 5};      // 完整初始化
int c[5] = {1, 2};               // 其余自动补 0 → {1,2,0,0,0}
int d[] = {1, 2, 3};             // 不写长度,编译器自动算 3
int e[3][4];                     // 二维数组

⭐ 与 Java 的三大致命差异

Java C
长度 a.length 属性 没有长度信息,只能自己记或用 sizeof
越界 抛 ArrayIndexOutOfBoundsException 不报错!直接读到别的内存 → 未定义行为
本质 独立的对象 数组名就是首元素地址(退化为指针)
int a[5] = {1, 2, 3, 4, 5};
printf("%d\n", a[10]);        // ⚠️ 不报错!读到垃圾数据甚至崩溃
int n = sizeof(a) / sizeof(a[0]);   // 唯一能自动算长度的办法(仅限本作用域)

⚠️ 数组一旦传给函数,就退化成指针,sizeof 拿到的是指针大小(8),不是数组长度!所以在函数里必须额外传长度参数。

数组名与指针的关系(记住这个等价式)

a[i]  ==  *(a + i)      // 下标运算本质就是指针运算的语法糖
&a[0] ==  a             // 数组名 = 首元素地址

遍历方式

// 下标方式
for (int i = 0; i < n; i++) printf("%d ", a[i]);

// 指针方式
for (int *p = a; p < a + n; p++) printf("%d ", *p);

Java 的 for (int x : a) 在 C 里不存在,只能上面两种。

字符串就是特殊的字符数组(见 11-字符串)

char s[] = "hello"; → 实际是 {'h','e','l','l','o','\0'},长度 6。

关联

09-指针 · 11-字符串 · 07-函数与作用域