当我想将2d数组输入函数时,为什么会出现这个错误(图1)?
#include <stdio.h>
#include <stdlib.h>
void pr(int** a){
printf("%d", a[0][0]);
}
int main(){
int a[5][5]={{1,4,7,11,15},{2,5,8,12,19},{3,6,9,16,22},{10,13,14,17,24},{18,21,23,26,30}};
pr(a);
}
答案 0 :(得分:5)
核心问题是数组和指针不一样(尽管它们密切相关),而2D数组也不是指针数组。
此代码显示了解决问题的三种方法。数组a0
是您重命名和重新格式化的数组;数组a
是一个指针数组,每个指针都是一个指向5 int
数组的指针,通过'复合文字',这是一个添加到C99的功能。我已经升级了打印功能,以打印传递给它的所有25个元素元素 - 并创建了两个具有不同接口的新打印功能,这些接口也打印传递给它们的整个数组。我假设阵列是方形的;矩形(非方形)矩阵可以很容易地处理,尤其是pr1()
上的变体,例如pr2(int n, int m, int a[n][m])
- 与pr1()
几乎完全相同,但需要在内部进行单一调整以测试{ {1}}反对j
而不是m
。
n
样本输出非常均匀:
#include <stdio.h>
static void pr0(int a[][5]);
static void pr1(int n, int a[n][n]);
static void pr(int **a)
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
printf("%3d", a[i][j]);
putchar('\n');
}
putchar('\n');
}
int main(void)
{
int a0[5][5] =
{
{ 1, 4, 7, 11, 15 },
{ 2, 5, 8, 12, 19 },
{ 3, 6, 9, 16, 22 },
{ 10, 13, 14, 17, 24 },
{ 18, 21, 23, 26, 30 },
};
int *a[] =
{
(int[]){ 1, 4, 7, 11, 15 },
(int[]){ 2, 5, 8, 12, 19 },
(int[]){ 3, 6, 9, 16, 22 },
(int[]){ 10, 13, 14, 17, 24 },
(int[]){ 18, 21, 23, 26, 30 },
};
pr(a);
pr0(a0);
pr1(5, a0);
return 0;
}
static void pr0(int a[][5])
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
printf("%3d", a[i][j]);
putchar('\n');
}
putchar('\n');
}
static void pr1(int n, int a[n][n])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
printf("%3d", a[i][j]);
putchar('\n');
}
putchar('\n');
}
三个街区是一样的。给定一个选择,我将在 1 4 7 11 15
2 5 8 12 19
3 6 9 16 22
10 13 14 17 24
18 21 23 26 30
1 4 7 11 15
2 5 8 12 19
3 6 9 16 22
10 13 14 17 24
18 21 23 26 30
1 4 7 11 15
2 5 8 12 19
3 6 9 16 22
10 13 14 17 24
18 21 23 26 30
中使用该技术,在接口中使用VLA(可变长度数组)。如果你必须坚持pr1()
参数,你必须坚持使用数组int **
,或者类似的东西。当然还有其他方法来创造它。例如:
a
答案 1 :(得分:4)
在所有可能的用例中,数组和指针不能互换使用,而您恰巧偶然发现其中一个。有时,int
数组可以隐式转换为指针,有时它也不应该是。
在您的情况下,隐式(或显式)将a转换为(int **
)将不起作用,因为a
在被视为指针时指向2d数组中的第一个元素。将a转换为int **
会使pr
丢失a
作为数组的信息。因此,将其作为int **
中的典型(pr
)处理并尝试将其解除引用两次会导致a
(a[0][0] = 1
)中的第一个元素作为地址处理并且会查找该地址中的值,我认为这不是pr()
的理想行为。
理想情况下,您应该以将2D数组作为参数而不是pr
的方式声明int **
。下面给出了pr
与所提及的修复的声明。
void pr(int a[][5]){
printf("%d", a[0][0]);
}
现在,您在评论的评论中提到pr
的定义无法修改。为了不修改pr()
,您必须将main
中的数据结构更改为类似于下面给出的数据结构。
int main(){
int a0[5]={1,4,7,11,15};
int a1[5]={2,5,8,12,19};
int a2[5]={3,6,9,16,22};
int a3[5]={10,13,14,17,24};
int a4[5]={18,21,23,26,30};
int *a[5] = {a0, a1, a2, a3, a4};
pr(a);
}
请注意,上面的示例并不是实现目标的语法最简洁的方法。另外,请检查here以查看此用法。