Двойной массив через указатели в C - PullRequest
0 голосов
/ 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;
}

Ответы [ 2 ]

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

У этого оператора есть несколько проблем:

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.

Кажется, вы делаете это немного сложнее, чем нужно.Существует два способа построения двумерного массива.Вы можете создать массив, используя 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 голосов
/ 18 сентября 2010

Это довольно искаженный синтаксис. Обычно, когда вы делаете 2D-массив:

  • Декларация просто int *p;
  • Распределение просто p = malloc(a*b*sizeof(int));
  • Вы не можете написать p[i][j]. Вы должны сделать одну из нескольких вещей - либо создать вторичный массив int **q, который содержит указатели строк, чтобы иметь возможность писать q[i][j] (лучшая производительность и удобочитаемость), либо писать p[b*i + j] (меньше шагов).

Кроме того, обратите внимание, что:

  • Ваш printf будет выбрасывать мусор из-за отсутствующего параметра% d.
  • Поскольку 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 - массив указателей на массивы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...