C语言二维数组函数传参报错及随机数填充异常求助
问题描述
我想要创建两个矩阵并为其填充0-9的随机数,但原代码中的fillM和printM函数使用void fillM(int array[a][b])这类定义时,因标识符a、b未定义而无法运行;使用#define定义a、b为固定值时可正常运行。修改函数参数传递矩阵尺寸后,程序运行时矩阵所有位置均填充相同随机数,希望得到解决方法。
原代码
#include <stdio.h> #include <float.h> #include <stdbool.h> #include <stdlib.h> #include <time.h> //fill random void fillM(int array[a][b]) { for (int x=0; x < a; x++) { for (int y=0; y < b; y++) { array[x][y] = rand()%10; } } } //print void printM(int array[a][b]){ for (int x=0; x < a; x++){ for (int y=0; y < b; y++) { printf("%d ", array[a][b]); } printf("\n"); } } int Main(){ //do I really need this? srand (time(NULL)); //set size int n; printf("please set size of n x n Matrix: \n"); scanf("%d", &n); int m = n; //initialise int m1[n][m]; int m2[n][m]; fillM (m1); fillM (m2); return 0; }
修改后代码
#include <float.h> #include <stdbool.h> #include <stdlib.h> #include <time.h> #include <stdio.h> //fill random void fillM(size_t a, size_t b, int array[a][b]) { for (int x=0; x < a; x++) { for (int y=0; y < b; y++) { array[x][y] = rand()%10; } } } //print void printM(size_t a, size_t b, int array[a][b]){ for (int x=0; x < a; x++){ for (int y=0; y < b; y++) { printf("%d ", array[a][b]); } printf("\n"); } printf("\n"); } int main(){ srand (time(NULL)); //set size int n; printf("please set size of n x n Matrix: \n"); scanf("%d", &n); printf("\n"); int m = n; //initialise int m1[n][m]; int m2[n][m]; fillM (n, m, m1); fillM (n, m, m2); printM (n, m, m1); printM (n, m, m2); return 0; }
问题分析与解决方法
1. 核心问题:打印函数的越界访问
修改后的代码中,printM函数存在严重错误:循环中始终访问array[a][b],而a和b是矩阵的整体尺寸,数组的合法索引范围是0到a-1、0到b-1,array[a][b]属于数组越界访问,会读取到内存中不确定的值,导致所有位置输出相同内容。
修复方法:将printM中的array[a][b]改为array[x][y],使用当前循环的索引访问对应位置的元素:
//print void printM(size_t a, size_t b, int array[a][b]){ for (int x=0; x < a; x++){ for (int y=0; y < b; y++) { printf("%d ", array[x][y]); // 修复索引错误 } printf("\n"); } printf("\n"); }
2. 函数参数与变长数组的规范
原代码中void fillM(int array[a][b])的写法不符合C标准,因为a和b未提前声明。修改后的代码将尺寸参数size_t a, size_t b放在数组参数之前,这是C99及以后标准支持的**变长数组(VLA)**写法,是正确的。
如果需要更好的兼容性,可以统一变量类型:将main函数中的n和m定义为size_t(与函数参数类型一致),避免类型转换的潜在问题:
size_t n; printf("please set size of n x n Matrix: \n"); scanf("%zu", &n); // 使用%zu作为size_t类型的格式化输入符 size_t m = n;
3. 随机数生成的正确性
你已经在main开头调用了srand(time(NULL))初始化随机数种子,这部分是正确的,确保每次运行程序生成的随机序列不同。fillM函数中rand()%10可以正确生成0-9的随机整数,无需修改。
内容的提问来源于stack exchange,提问作者Enno Mühlbauer
相关产品推荐
相关产品推荐

