C语言实现bubble method时数组首元素出现随机大负数问题
问题描述
- 发帖人为编程入门学习者,首次在平台发帖,当前正在学习bubble method(冒泡排序)
- 代码整体运行逻辑基本正常,但排序输出时数组第一个元素始终显示无规律的随机超大负数:
实际运行输出:
-858993460, 2, 2, 3, 5,
预期正确输出:2, 2, 3, 5, 8 - 程序通过
srand初始化随机数种子自动填充数组,无需手动输入数值即可连续开展排序功能测试,西语使用者也可使用西班牙语解答。
问题根因
代码存在数组越界访问的未定义行为:
你声明的数组长度为5,合法下标范围是0~4。但原冒泡排序内层循环的判断条件为j < cantElementos,当j循环到4时,代码会访问array[j+1]也就是array[5],这个位置不属于你申请的数组内存范围,是栈上未初始化的垃圾空间——你看到的-858993460是VS编译器默认填充在未初始化栈空间的0xCCCCCCCC,转为32位有符号整数正好是这个负数。后续的交换操作会把这个垃圾值写入数组的合法位置,直接导致排序结果异常。
另外原内层循环没有做轮次优化,每一轮都会重复比较前几轮已经沉到末尾的有序元素,属于无效运算,可以顺手优化。
修复方案
- 修改内层循环边界条件:将
j < cantElementos改为j < cantElementos - i - 1,既保证j+1始终落在数组合法下标范围内,避免越界,也能跳过每一轮已经排好序的末尾元素,减少不必要的比较。 - 修正原代码中
printf的换行写法,用转义字符\n实现换行,避免字符串直接换行带来的语法问题。
修复后完整代码
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <stdlib.h> #include <string.h> #include <time.h> using namespace std; void randomArray(int[], int); void mostrarArray(int[], int); int main() { int i = 0, j = 0, array[5], cantElementos = 5, aux = 0; srand(time(NULL)); randomArray(array, cantElementos); printf("原始数组为:\n"); mostrarArray(array, cantElementos); for (i = 0; i < cantElementos; i++) { // 修正内层循环边界,解决越界问题同时优化性能 for (j = 0; j < cantElementos - i - 1; j++) { if (array[j] > array[j + 1]) { aux = array[j]; array[j] = array[j + 1]; array[j + 1] = aux; } } } printf("\nEl array arreglado es:\n"); mostrarArray(array, cantElementos); return 0; } void randomArray(int array[], int cantElementos) { int i = 0; for (i = 0; i < cantElementos; i++) { array[i] = rand() % 10 + 1; } } void mostrarArray(int array[], int cantElementos) { int i = 0; for (i = 0; i < cantElementos; i++) { printf("%d, ", array[i]); } printf("\n"); }
内容的提问来源于stack exchange,提问作者Valentín Sanabria
相关产品推荐
相关产品推荐

