当我要向函数输入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);
}发布于 2017-01-14 06:59:08
核心问题是数组和指针是不一样的(尽管它们是密切相关的),而2D数组不是指针数组。
这段代码展示了解决问题的三种方法。数组a0是重命名和重新格式化的数组;数组a是一个指针数组,每个指针都是通过“复合文字”指向5 int数组的指针,这是添加到C99的一个特性。我升级了打印功能,以打印传递给它的数组中的所有25个元素,并创建了两个具有不同接口的新打印函数,它们也打印传递给它们的整个数组。我假设数组是正方形的;矩形(非方形)矩阵可以很容易地处理,特别是通过pr1()上的一个变体,比如pr2(int n, int m, int a[n][m]) --它几乎与pr1()相同,但需要在内部进行一次调整,以测试针对m而不是n的j。
#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这三个街区是一样的。如果有选择,我会在pr1()中使用这种技术,在接口中使用VLA(可变长度数组)。如果必须坚持使用int **参数,则必须坚持使用数组a或类似的内容。当然还有其他方法来创造这一点。例如:
int *a[] = { a0[0], a0[1], a0[2], a0[3], a0[4] };发布于 2017-01-14 06:41:50
数组和指针不能在所有可能的用例中交替使用,您只是碰巧碰到了其中的一个。有时,可以隐式地将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);
}请注意,上面的示例并不是实现目标的最简洁的语法方法。此外,请检查这里以查看此用法是否有效。
https://stackoverflow.com/questions/41647445
复制相似问题