不兼容的指针类型将int [5] [5]传递给int类型的参数**

时间:2017-01-14 06:32:56

标签: c

当我想将2d数组输入函数时,为什么会出现这个错误(图1)?

enter image description here

#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);
}

2 个答案:

答案 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)处理并尝试将其解除引用两次会导致aa[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以查看此用法。