C语言中填充vector/matrix后打印显示垃圾值问题求助
数组填充后打印出现随机垃圾值的问题解决
问题描述
尝试在函数间打印vector,但填充vector或matrix后,离开对应函数时数据会丢失,导致打印出随机垃圾值。以下是相关代码:
#include <stdio.h> #include <stdlib.h> #include <time.h> void menu(); void fillVector1(int vector[], int size); void fillVector2(int vector[], int size); void fillVector3(int vector[], int vector1[], int vector2[], int size); void fillMatrix(int matrix[][5], int size); void printVector(int vector[], int size); void printMatrix(int matrix[][5], int size); int main() { menu(); return 0; } void menu() { int option; int vector1[10]; int vector2[10]; int vector3[20]; int matrix[5][5]; printf("ARRAYS MENU"); printf("\n\t1.- Fill Vector 1\n\t2.- Fill Vector 2\n\t3.- Fill Vector 3\n\t4.- Print Vectors\n\t5.- Fill Matrix 4x4\n\t6.- Print Matrix\n\t0.- Close Program\n"); printf("Select an option: "); scanf("%i", &option); switch (option) { case 1: fillVector1(vector1, 10); break; case 2: fillVector2(vector2, 10); break; case 3: fillVector3(vector3, vector1, vector2, 10); printVector(vector3, 10); break; case 4: printf("\n"); printVector(vector1, 10); printf("\n"); printVector(vector2, 10); printf("\n"); printVector(vector3, 20); break; case 5: fillMatrix(matrix, 4); break; case 6: printMatrix(matrix, 4); break; case 0: printf("Thanks for using this program. Come back soon!"); break; default: printf("Invalid option. Select another one."); break; } } void fillVector1(int vector[], int size) { printf("Fill it only with numbers between 30 to 70\n"); for (int i = 0; i < size; i++) { printf("Vector[%i]: ", i); scanf("%i", &vector[i]); if (vector[i] < 30 || vector[i] > 70) { printf("Value out of range. Please enter another number.\n"); i--; // repeat last (incorrect) index } } menu(); } void fillVector2(int vector[], int size) { printf("Vector filled with random numbers between 1 to 20"); int checkRepeated; srand(time(NULL)); for (int i = 0; i < size; i++) { // function to avoid repeated number do { checkRepeated = 0; // initialize to assume the number is not repeated vector[i] = rand() % 20 + 1; // check if the random number already exists in the vector for (int j = 0; j < i; j++) { if (vector[j] == vector[i]) { checkRepeated = 1; // set to 1 if the number is repeated break; } } } while (checkRepeated); // repeat until a unique number is generated } menu(); } void fillVector3(int vector[], int vector1[], int vector2[], int size) { for (int i = 0; i < size; i++) { vector[i] = vector1[i]; vector[i + 10] = vector2[i]; } menu(); } void fillMatrix(int matrix[][5], int size) { for (int r = 0; r < size; r++) { for (int c = 0; c < size; c++) { printf("Matrix[%i, %i]: ", r, c); scanf("%i", &matrix[r][c]); } } menu(); } void printVector(int vector[], int size) { printf("Vector elements: {"); for (int i = 0; i < size; i++) { printf("%d", vector[i]); if (i < size - 1) { printf(", "); } } printf("}"); } void printMatrix(int matrix[][5], int size) { int r, c; printf("Matrix elements: \n{\n"); for (r = 0; r < size; r++) { for (c = 0; c < size; c++) { printf("%d\t", matrix[r][c]); } printf("\n"); } printf("}"); }
问题原因
核心问题是递归调用menu()函数:
- 每次调用
menu(),都会在栈上创建新的局部数组vector1、vector2、vector3、matrix,这些数组的生命周期仅限于当前menu()函数的栈帧。 - 当你在
fillVector1等填充函数完成后调用menu(),原来的menu()栈帧会被销毁,其中填充好的数组数据也随之消失。新调用的menu()里的数组是未初始化的,打印时自然输出随机垃圾值。
解决方案
把menu()改成循环结构,去掉递归调用,让填充函数执行完后返回原menu()的循环,这样数组的生命周期会持续到整个程序运行期间(因为数组在menu()的循环内,每次循环复用同一个数组)。
修改后的代码
#include <stdio.h> #include <stdlib.h> #include <time.h> void menu(); void fillVector1(int vector[], int size); void fillVector2(int vector[], int size); void fillVector3(int vector[], int vector1[], int vector2[], int size); void fillMatrix(int matrix[][5], int size); void printVector(int vector[], int size); void printMatrix(int matrix[][5], int size); int main() { menu(); return 0; } void menu() { int option; // 将数组声明在循环外,保证生命周期覆盖整个菜单交互过程 int vector1[10]; int vector2[10]; int vector3[20]; int matrix[5][5]; // 用do-while循环替代递归,实现菜单循环 do { printf("\nARRAYS MENU"); printf("\n\t1.- Fill Vector 1\n\t2.- Fill Vector 2\n\t3.- Fill Vector 3\n\t4.- Print Vectors\n\t5.- Fill Matrix 4x4\n\t6.- Print Matrix\n\t0.- Close Program\n"); printf("Select an option: "); scanf("%i", &option); switch (option) { case 1: fillVector1(vector1, 10); break; case 2: fillVector2(vector2, 10); break; case 3: fillVector3(vector3, vector1, vector2, 10); printf("\n"); printVector(vector3, 20); // 修正原代码打印长度错误 break; case 4: printf("\nVector 1: "); printVector(vector1, 10); printf("\nVector 2: "); printVector(vector2, 10); printf("\nVector 3: "); printVector(vector3, 20); break; case 5: fillMatrix(matrix, 4); break; case 6: printf("\n"); printMatrix(matrix, 4); break; case 0: printf("\nThanks for using this program. Come back soon!"); break; default: printf("\nInvalid option. Select another one."); break; } } while (option != 0); // 直到选择0才退出循环 } void fillVector1(int vector[], int size) { printf("\nFill it only with numbers between 30 to 70\n"); for (int i = 0; i < size; i++) { printf("Vector[%i]: ", i); scanf("%i", &vector[i]); if (vector[i] < 30 || vector[i] > 70) { printf("Value out of range. Please enter another number.\n"); i--; // repeat last (incorrect) index } } // 去掉menu()递归调用,直接返回原menu循环 } void fillVector2(int vector[], int size) { printf("\nVector filled with random numbers between 1 to 20\n"); int checkRepeated; srand(time(NULL)); for (int i = 0; i < size; i++) { // function to avoid repeated number do { checkRepeated = 0; // initialize to assume the number is not repeated vector[i] = rand() % 20 + 1; // check if the random number already exists in the vector for (int j = 0; j < i; j++) { if (vector[j] == vector[i]) { checkRepeated = 1; // set to 1 if the number is repeated break; } } } while (checkRepeated); // repeat until a unique number is generated } // 去掉menu()递归调用 } void fillVector3(int vector[], int vector1[], int vector2[], int size) { for (int i = 0; i < size; i++) { vector[i] = vector1[i]; vector[i + 10] = vector2[i]; } // 去掉menu()递归调用 } void fillMatrix(int matrix[][5], int size) { printf("\nFill Matrix 4x4:\n"); for (int r = 0; r < size; r++) { for (int c = 0; c < size; c++) { printf("Matrix[%i, %i]: ", r, c); scanf("%i", &matrix[r][c]); } } // 去掉menu()递归调用 } void printVector(int vector[], int size) { printf("Vector elements: {"); for (int i = 0; i < size; i++) { printf("%d", vector[i]); if (i < size - 1) { printf(", "); } } printf("}"); } void printMatrix(int matrix[][5], int size) { int r, c; printf("Matrix elements: \n{\n"); for (r = 0; r < size; r++) { for (c = 0; c < size; c++) { printf("%d\t", matrix[r][c]); } printf("\n"); } printf("}"); }
额外修正点
- 原代码中
case 3打印vector3时传入的size是10,而vector3实际是20个元素,修改为20以保证完整打印。 - 在菜单和各函数中添加换行,优化输出可读性。
内容的提问来源于stack exchange,提问作者kewvy
相关产品推荐
相关产品推荐

