【问题标题】:Double array through pointers in C通过C中的指针进行双数组
【发布时间】:2010-09-17 21:02:18
【问题描述】:

我想在指针的帮助下扫描一个二维数组并写了这段代码,你能告诉我为什么编译器会出错吗?

#include<stdio.h>
#include<stdlib.h>
int main(void) {
    int i,j,n,a,b;
    int (*(*p)[])[];
    printf("\n\tEnter the size of the matrix in the form aXb\t\n");
    scanf("%dX%d",&a,&b);
    p=(int (*(*p)[b])[a])malloc(b*sizeof(int (*p)[a]));
    for(i=0;i<b;i++) {
            p[i]=(int (*p)[a])malloc(a*sizeof(int));
            printf("\t\bEnter Column %d\t\n");
            for(j=0;j<a;j++)
                    scanf("%d",&p[i][j]);
    }
    return 0;
}

【问题讨论】:

  • 您遇到了什么错误?你用的是什么编译器?你是用 C 还是 C++ 构建的?
  • 别忘了free你分配内存的所有对象。
  • 你明白什么是指针吗?从这段代码看来,你认为它是一个数组,来自int (*(*p)[])[];,这是完全错误的。

标签: c pointers multidimensional-array


【解决方案1】:

这个说法有几个问题:

p=(int (*(*p)[b])[a])malloc(b*sizeof(int (*p)[a]));

首先,malloc 返回一个void*。您正在使用 (int (*(*p)[b])[a]) 转换该指针,它会产生一个值,而不是数据类型。这不是一个有效的演员表,所以这是编译器对你大喊大叫的原因之一。此时,p 尚未初始化,因此如果执行此语句,此处发生的取消引用可能会使您的程序崩溃。

在您的malloc 调用中,您使用的是sizeof(int (*p)[a])。语句 int (*p)[a] 不是有效的 C 语句。

您似乎使这变得更复杂了。有两种构建二维数组的方法。正如 Reinderien 解释的那样,您可以使用 malloc(a * b * sizeof(int)) 构建一个数组。您还可以构建一个一维指针数组,每个指针指向一个int 类型的数组。从您的代码来看,您似乎正在尝试执行后者。

更简单的方法是这样的:

int **p;
... get input from user ...
// Declare an array of int pointers of length b
p = malloc(b * sizeof(int*));

// For each int* in 'p' ...
for (i = 0; i < b; ++i) {
    // ... allocate an int array of length 'a' and store a pointer in 'p[i]' ..
    p[i] = malloc(a * sizeof(int));
    // ... and fill in that array using data from the user
    printf("\t\bEnter Column %d\t\n");
    for(j = 0; j < a; j++)
        scanf("%d", &p[i][j]);
}

使用这种构建二维数组的方法允许您使用语法p[x][y]。由于p 是指向指针的指针,p[x] 是指向数组的指针,p[x][y] 是指向数组中的一项。

【讨论】:

    【解决方案2】:

    这是一些相当扭曲的语法。通常当你制作一个二维数组时:

    • 声明就是int *p;
    • 分配简直就是p = malloc(a*b*sizeof(int));
    • 你不能写p[i][j]。您必须做几件事之一 - 要么创建一个包含行指针的辅助数组 int **q,以便能够写入 q[i][j](更好的性能和易读性),要么编写 p[b*i + j](更少的步骤)。

    另外,请注意:

    • 由于缺少 %d 参数,您的 printf 将喷出垃圾。
    • 由于 C 不是类型安全的,因此使用 scanf 将隐藏您可能犯的任何间接错误。

    关于我能想到的与您尝试做的最接近的事情:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int i, j;
    
        const int a = 3, b = 4;
        int m[4][3];
        int (*p[4])[3];
    
        for (i = 0; i < b; i++)
        {
            p[i] = &m[i];
            printf("\t\bEnter Column %d\t\n", i);
            for (j = 0; j < a; j++)
            {
                int x;
                scanf("%d", &x);
                (*p[i])[j] = x;
            }
        }
        return 0;
    }
    

    它可以按预期编译和运行,但它毫无意义地复杂。 p 是一个指向数组的指针数组。

    【讨论】:

    • 当您放置答案时,我正在编写完全相同的“扭曲语法”行。确实,n0nChun 阅读了他的答案,他不仅仅是简单地给你代码,而是解决这个问题的实际方法。请注意您的代码格式和编码风格,这将是导致这些类型错误/错误的更多原因。
    • @Yon:我没有其他方法,我只是在尝试这个。
    • @Rein:我实际上想知道我编写的代码出了什么问题,而不是想知道如何绕过它来解决问题。
    • 如果你“没有[原文如此]另一种方法”,而另一种方法更简单十倍更容易理解,那么......?
    • 无论如何,你想要做的不仅是一个糟糕的想法,而且是不可能的。由于ab 不是常量,所以不能形成长度为ab 的数组类型。如果它们是恒定的,你可以,但这会破坏使用 malloc 的全部目的。
    猜你喜欢
    • 2012-02-25
    • 1970-01-01
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    相关资源
    最近更新 更多