写代码时突然蹦出个“数组越界”的编译器报错,很多人第一反应是懵。其实这问题挺常见,尤其在用 C、C++ 或 Java 写程序的时候。说白了,就是你让程序去访问一个根本不存在的数组位置,比如总共只有5个格子的数组,你非要去第6个位置拿数据,系统当然不干。
啥叫数组越界?
想象你在小区里送快递,一栋楼有5层,每层一户人家。你手里的单子写着送到3楼,没问题。但如果写成送到6楼,可这栋楼压根没6楼,这任务就执行不了。数组也一样。定义一个长度为5的数组,合法的索引是0到4(从0开始数),一旦用了5或更大的数字,就越界了。
常见的出错场景
比如你写了一段 C 语言代码:
int numbers[5] = {10, 20, 30, 40, 50};
for (int i = 0; i <= 5; i++) {
printf("%d\n", numbers[i]);
}
看着好像没啥问题,循环从0到5,一共6次。但数组只有5个元素,最大索引是4。当 i 等于5时,numbers[5] 就越界了。这个错误在编译阶段不一定被发现,但运行时可能直接崩溃,或者出现奇怪的数据。
Java 也不保险
有人觉得 Java 安全,不会出事,其实只是表现不一样。Java 在运行时会检查数组边界,一旦越界,直接抛出 ArrayIndexOutOfBoundsException。比如这段代码:
int[] arr = new int[3];
arr[3] = 100; // 错了!最大只能用 arr[2]
程序一跑就崩,提示异常。虽然不像 C 那样可能默默写坏内存,但功能照样没法用。
怎么避免这类问题?
最简单的办法是写循环时别硬编码长度。用语言自带的长度属性或宏。比如 C 语言可以用 sizeof 计算:
int len = sizeof(numbers) / sizeof(numbers[0]);
for (int i = 0; i < len; i++) {
printf("%d\n", numbers[i]);
}
Java 更方便,直接用 arr.length:
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
这样哪怕以后数组长度变了,循环也不会跟着出错。
调试小技巧
遇到越界报错,先看编译器或运行环境提示的具体行号。找到那行代码,检查数组名和下标。打印一下数组长度和当前下标值,对比看看是不是超了。尤其是循环里带复杂计算的下标,比如 i + 1、index * 2 这类,最容易在边界处翻车。
还有一种情况是动态输入导致的,比如用户输入一个数字当索引。这时候不做判断就直接访问数组,风险很大。加个条件判断,确保下标在合理范围内,能省不少麻烦。