第六章:派生数据类型
级别 1 — 入门
从基本类型构建复杂数据结构:数组、指针、结构体和类型别名。
C 从基本构建块派生出复杂类型。数组将相同类型的元素在内存中连续排列。指针间接引用其他对象。结构体将异构字段捆绑为一个单元。类型别名为现有类型赋予新名字。Auto 以更简洁的语法提供了所有这些功能。
6.1 数组
数组是相同类型元素的固定大小序列,在内存中连续存储。数组大小是其类型的一部分,运行时不能改变。
c
// C
int primes[5] = { 2, 3, 5, 7, 11 };
printf("first = %d\n", primes[0]); // first = 2
printf("count = %zu\n", sizeof(primes)/sizeof(primes[0])); // count = 5auto
// Auto
let primes [5]int = [5]int{2, 3, 5, 7, 11}
print("first =", primes[0])
print("count =", len(primes))主要区别:
| 特性 | C | Auto |
|---|---|---|
| 声明 | int a[5]; | let a [5]int |
| 类型中的大小 | 前缀:int a[N] | 后缀:[N]int |
| 数组长度 | sizeof(a)/sizeof(a[0]) | len(a) |
| 边界检查 | 无(未定义行为) | 运行时检查(默认) |
| 多维数组 | int m[3][4] | [3][4]int |
数组到指针的退化: 在 C 中,数组名在大多数上下文中会退化为指向其第一个元素的指针。这是许多微妙 bug 的根源。Auto 没有这种退化——数组保持为数组。
c
// C:退化行为
int a[5] = {1,2,3,4,5};
int *p = a; // a 退化为 &a[0]
p[10] = 99; // 未定义行为:越界要点: C 数组没有边界检查。对 5 元素数组访问
a[10]能编译但不报错,会破坏内存。Auto 默认插入运行时边界检查。