【问题标题】:2D array through pointers通过指针的二维数组
【发布时间】:2010-09-18 08:54:02
【问题描述】:

我想在指针的帮助下扫描一个二维数组并编写了这段代码,你能告诉我为什么编译器会出错吗?我知道如何使用双指针来做同样的事情,我正在试验这个。

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

【问题讨论】:

  • 它可以帮助列出编译器错误,你知道的。 ;-)
  • “这个”是什么意思?构造 (int (*(*p)[b])[a]) ??那该怎么办?我的 gcc 似乎不喜欢那样。
  • determinant.c:9: error: expected ')' before 'p'determinant.c:9: error: expected ')' before '[' tokendeterminant.c:9: error: expected ')' 在 '[' 令牌确定性.c:9 之前:错误:预期';' 在'malloc'确定性.c:11 之前:错误:无效使用未指定边界的数组确定性.c:11:错误:预期') '在'p'之前determinant.c:11:错误:预期')'在'['令牌determinant.c:11之前:错误:无效使用未指定边界的数组determinant.c:11:错误:预期';'之前“malloc”determinant.c:14:错误:无效使用未指定边界的数组

标签: c pointers multidimensional-array


【解决方案1】:

你正在使用指向数组的指针,所以你不应该直接索引它们,因为p[i] 将给出*(p+i),即一个跟随 p 指向的数组,而不是 p 的元素。

在 C 中,void* 将转换为任何指针类型,因此您不需要强制转换 malloc 的结果。如果您确实放入了强制转换,它可以掩盖错误,例如,如果您尝试分配给非指针(例如 p[i] )。

在 p 的 malloc 中,sizeof(int (*p)[a]) 应该使用类型或表达式,而不是声明。 p 是指向 int 数组的指针数组的指针,因此 *p 的元素类型为 int (*)[]

所以在 gcc 上编译没有错误或警告:

#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 = malloc ( b * sizeof ( int ( * ) [] ) );

    for ( i = 0;i < b;i++ ) {
        ( *p ) [i] = malloc ( a * sizeof ( int ) );
        printf ( "\t\bEnter Column %d\t\n", i );
        for ( j = 0;j < a;j++ )
            scanf ( "%d", & ( * ( *p ) [i] ) [j] );
    }


    return 0;
}

但是,由于使用指向数组的指针与使用指向其第一个元素的指针相比没有优势,但这确实意味着您必须在获取元素之前取消引用,因此使用指向指针形式的指针要容易得多.

【讨论】:

  • 这是一个绝妙的答案。谢谢! :)
【解决方案2】:

你知道int (*(*p)[])[]是什么吗?
试试 cdecl.org ...http://cdecl.ridiculousfish.com/?q=int+%28%2A%28%2Ap%29%5B%5D%29%5B%5D

使用一维数组并假装它是一个二维数组

  1. 声明一维对象(指针、数组等)
  2. malloc 一个矩形大小
  3. 根据行、列和列大小计算线性寻址值
  4. 使用它
  5. 释放数组

就是这样

/* Oh ... and use spaces in your code */
/* They are extremely cheap now a days */
#include <assert.h>
/* instead of asserting malloc and scanf, use proper error checking */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int i, j, n, rows, cols;
    int *p;                                            /* 1. */

    printf("Enter the size of the matrix in the form aXb\n");
    n = scanf("%dX%d", &rows, &cols);
    assert((n == 2) && ("scanf failed"));
    p = malloc(rows * cols * sizeof *p);               /* 2. */
    assert((p != NULL) && "malloc failed");
    for (i = 0; i < rows; i++) {
            int rowindex = i * cols;                   /* 3. */
            for (j = 0; j < cols; j++) {
                    n = scanf("%d", &p[rowindex + j]); /* 3. and 4. */
                    assert((n == 1) && "scanf failed");
            }
    }
    free(p);                                           /* 5. */
    return 0;
}

【讨论】:

    【解决方案3】:

    您不必要地使使用指针访问数组元素的问题复杂化。 尝试使用简单的指针到指针 p。

    int **p;
    ...
    p=malloc(a*sizeof(int *));   //create one pointer for each row of matrix
    ...
    for(i=0;i<a;i++)
    {
    ...
    p[i]=malloc(b*sizeof(int));  //create b integers in each row of matrix
    ...
    }
    

    【讨论】:

    • 您可能希望“使用”对象(而不是类型)作为 sizeof 运算符的参数。如果以后把p改成double **p,就不需要用mallocs改行p = malloc(a * sizeof *p);p[i] = malloc(b * sizeof *p[i]);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 2018-04-17
    • 2011-08-15
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    相关资源
    最近更新 更多