Skip to content

数组 ​

CIN 的数组分两种写法, 语义不同, 必须分清:

写法名称语义
int a[5]、float m[3][4]固长数组值语义, 在数据区/栈上就地分配, 生命周期与声明它的作用域一致
int[] arr、int[][] g指针形式数组只保存基址 (指针), 用于参数、返回值和需要运行时决定长度的场合

数组下标从 0 开始, 多维数组按行主序存放。

声明与默认值 ​

cin
int a[5]                        // 一维, 全部为 0
float m[3][4]                   // 二维 (3 行 4 列, 行主序)
int init[4] = {1, 2, 3, 4}      // 字面量初始化
int ident[2][2] = { {1, 0}, {0, 1} }
string names[3]                 // 字符串数组 (三个空串指针)
  • 未初始化的固长数组全部为类型默认值 (int → 0, float → 0.0, string → "");
  • 字面量可以嵌套表示多维; 元素个数超过声明维度会报错;
  • 固长数组可以出现在全局、局部以及 struct 字段位置。

下标访问 ​

cin
int a[5] = {10, 20, 30, 40, 50}
println(int_to_str(a[0]))          // 10
a[4] = 99
println(int_to_str(a[4]))          // 99

float m[2][3] = { {1, 2, 3}, {4, 5, 6} }
println(int_to_str(m[1][2]))       // 6   (第 2 行第 3 列)

逐维下标: m[day][hour]; 数组名当作表达式使用时就是基址指针。

遍历 ​

定长数组可以直接用范围 for 遍历 (不用自己维护下标):

cin
int a[5] = {10, 20, 30, 40, 50}
int total = 0
for (int v : a) {
    total = total + v          // 150
}
  • 被遍历对象必须是定长数组; int[] 指针形式参数与多维数组不支持, 请用下标循环 (range-for requires a fixed-size array);
  • 循环变量是元素的拷贝, 修改它不会影响原数组;
  • 完整规则见 控制流 · 范围 for。

默认不做越界检查

与 C 一样, CIN 默认不检查数组越界, 越界读写会踩到相邻数据。需要检查时加 --bounds-check (编译期把检查注入字节码, 与 Go 原生引擎兼容):

bash
codecin prog.cin --bounds-check

指针形式数组 ​

参数与返回值用 T[] 表示“不知道长度的数组”:

cin
function sum(int[] arr, int n) -> int {
    int s = 0
    for (int i = 0; i < n; i = i + 1) {
        s = s + arr[i]
    }
    return s
}

function main() -> int {
    int data[5] = {1, 2, 3, 4, 5}
    println(int_to_str(sum(data, 5)))     // 15
    return 0
}
  • 固长数组作参数时写 int[5] 也可以, 传入后衰减为指针形式;
  • 数组按引用传递: 函数内修改元素对调用方可见 (struct 参数同理, 见 struct);
  • 数组不携带长度, 因此所有库函数都要求额外传入 n (见 标准库参考)。

不要照抄“返回指针数组”的写法

int[] 作为函数返回类型在语法上存在, 但指向的堆块没有生命周期保证, 极易踩到脏数据。 需要返回多个值时, 更稳妥的做法是把结果写入调用方传入的数组:

cin
function divmod(int a, int b, int[] out2) -> void {
    out2[0] = idiv(a, b)
    out2[1] = a - idiv(a, b) * b
}

function main() -> int {
    int r[2]
    divmod(38, 7, r)
    println(int_to_str(r[0]) + " " + int_to_str(r[1]))   // 5 3
    return 0
}

与标准库配合 ​

内置库对数组的接口都是“数组 + 长度”的形式:

cin
import "array.cin"
import "sort.cin"

function main() -> int {
    int a[8] = {5, 3, 8, 1, 9, 2, 7, 4}
    sort_bubble(a, 8)                       // 原地升序
    println(int_to_str(a[0]) + " ... " + int_to_str(a[7]))
    println("sum = " + int_to_str(a_sum(a, 8)))
    println("max = " + int_to_str(a_max(a, 8)))
    return 0
}
text
1 ... 9
sum = 39
max = 9

更多函数 (查找、反转、复制、切片求和、二分) 见 标准库参考。

与字符串 ​

string 不是数组, 但可以用 s[i] 只读访问单个字节 (返回 0..255 的整数编码):

cin
string s = "Code CIN"
int c = s[0]              // 67 ('C')

字符串不可原地修改, s[i] = 65 是非法左值 —— 详见 字符串。

常见错误 ​

现象原因处理
结果被莫名其妙覆盖越界写踩到相邻变量打开 --bounds-check 定位
函数里改了数组但外面没变把数组当值传递的直觉数组是引用语义, 改动本来就可见; 若不可见说明传的是副本字段
字面量初始化报错元素个数超过声明维度对齐长度
遍历读到垃圾n 传错 (超出实际长度)CIN 不带长度, n 由调用方保证
range-for requires a fixed-size array用范围 for 遍历了 int[] 指针形式或形参改用定长数组或下标循环
Stack overflow局部大数组占满栈减小数组或 --mem-size 扩容

相关页面 ​

文档由 VitePress 构建