08 · 数组
声明与初始化
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。