2D массив с помощью указателей - PullRequest
2 голосов
/ 18 сентября 2010

Я хочу отсканировать 2D-массив с помощью указателей и написал этот код, не могли бы вы сказать мне, почему компилятор выдает ошибки? Я знаю как использовать двойные указатели, чтобы делать то же самое, я экспериментировал с этим.

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

Ответы [ 3 ]

1 голос
/ 18 сентября 2010

Знаете ли вы, что такое int (*(*p)[])[]?
Попробуйте cdecl.org ... http://cdecl.ridiculousfish.com/?q=int+%28%2A%28%2Ap%29%5B%5D%29%5B%5D

Чтобы использовать одномерный массив и представьте, что он 2-мерный

  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;
}
1 голос
/ 18 сентября 2010

Вы используете указатели на массивы, поэтому не следует индексировать их напрямую, так как p[i] даст *(p+i), т.е. массив, следующий за указанным на p, а не элемент p.

В C void* преобразуется в любой тип указателя, поэтому вам не нужно приводить результат malloc. Если вы введете приведение, оно может маскировать ошибки, например, если вы пытаетесь назначить не указатель (например, p[i]).

В malloc для p, 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;
}

Однако, поскольку использование указателя на массив не является преимуществом по сравнению с использованием указателя на его первый элемент, но это означает, что вам нужно разыменовать перед получением элемента, гораздо проще использовать указатель на форму указателя .

0 голосов
/ 18 сентября 2010

Вы излишне усложняете проблему доступа к элементам массива с помощью указателей. Попробуйте использовать простой указатель на указатель 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
...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...