Передача указателя на многомерный массив в качестве аргументов - PullRequest
0 голосов
/ 12 апреля 2019

Я новичок и пытаюсь понять, как работают многомерные массивы

Пожалуйста, посмотрите на этот код:

#include<stdio.h>

void getData(int c;int *a,int r,int c)
{
    for(int i=0;i<r;i++)
        for(int j=0;j<c;j++)
            scanf("%d",(*(a+i)+j)); //warning 
    return;
}

void putData(int c;int *a,int r,int c)
{
    for(int i=0;i<r;i++)
        for(int j=0;j<c;j++)
            printf("%d",*(*(a+i)+j));  //error
    printf("\n");
}

int main(void)
{
    int r1,r2,c1,c2;
    printf("Enter order of A:\n");
    scanf("%d %d",&r1,&c1);
    printf("Enter order of B:\n");
    scanf("%d %d",&r2,&c2);
    int a[r1][c1],b[r2][c2];
    getData((int *)a,r1,c1);
    getData((int *)b,r2,c2);
    putData((int *)b,r2,c2);
}

У меня проблемы с пониманием того, как передаются указателик функциям и причинам ошибок.Но я думаю, что если я смогу понять, как работают указатели, я мог бы отладить его.Пожалуйста помоги!Спасибо!

Редактировать: Я действительно хочу понять, как работает указатель с адресом и прочее.Так что, если есть какая-то трассировка, это может помочь мне

1 Ответ

2 голосов
/ 12 апреля 2019

Когда вы передаете VLA в качестве параметра (или любого 2D-массива в этом отношении), вы должны как минимум передать количество элементов в строке, чтобы вы могли объявить полный тип для вашего VLA (2D-массива).

Пока можно пройти:

void getData (int r, int c, int a[r][c])

Вы также можете передать:

void getData (int r, int c, int (*a)[c])

(поскольку первый уровень косвенности преобразуется в указатель, см .: Стандарт C11 - 6.3.2.1 Другие операнды - L-значения, массивы и указатели функций (p3) - и обратите внимание на исключения)

c должен быть включен в список параметров до a, иначе тип для a будет неполным, поскольку c еще не определено.

Хотя вы можете написать *(*(a + i) + j) в качестве эквивалентной записи указателя для a[i][j] - нет, это менее читабельно (но полностью эквивалентно).

Всегда, ВСЕГДА, всегда проверяйте КАЖДЫЙ ввод. В противном случае вы рискуете вызвать Undefined Behavior , следующий за input или , сопоставляя с ошибкой scanf, например,

    printf("Enter order of A:\n");
    if (scanf ("%d %d", &r1, &c1) != 2) {   /* validate EVERY input */
        fputs ("error: invalid input (r1, c1).\n", stderr);
        return 1;
    }

Если сложить все вместе, вы могли бы сделать:

#include <stdio.h>
#include <stdlib.h> /* for EXIT_FAILURE */

void getData (int r, int c, int (*a)[c])
{
    for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++)
            if (scanf ("%d", &a[i][j]) != 1) {
                fputs ("error: invalid input a[i][j].\n", stderr);
                exit (EXIT_FAILURE);
            }
}

void putData (int r, int c, int (*a)[c])
{
    for (int i = 0; i < r; i++) {
        for(int j = 0; j < c; j++)
            printf (" %2d", a[i][j]);   /* more readable */
            /* printf (" %2d", *(*(a + i) + j)); */
        putchar ('\n');  /* use putchar for a single char, instead of printf */
    }
}

int main(void)
{
    int r1, r2, c1, c2;

    printf ("Enter order of A:\n");
    if (scanf ("%d %d", &r1, &c1) != 2) {   /* validate EVERY input */
        fputs ("error: invalid input (r1, c1).\n", stderr);
        return 1;
    }

    printf ("Enter order of B:\n");
    if (scanf ("%d %d", &r2, &c2) != 2) {   /* validate EVERY input */
        fputs ("error: invalid input (r2, c2).\n", stderr);
        return 1;
    }
    int a[r1][c1], b[r2][c2];

    getData (r1, c1, a);
    getData (r2, c2, b);

    puts ("a");
    putData (r1, c1, a);
    puts ("\nb");
    putData (r2, c2, b);
}

( примечание: включение stdlib.h для макроса EXIT_FAILURE и обратите внимание на дополнительный интервал в коде - помогает старшим глазам)

Пример использования / Вывод

$ echo "2 3 2 3 1 2 3 4 5 6 7 8 9 10 11 12" | ./bin/scanfvla
Enter order of A:
Enter order of B:
a
  1  2  3
  4  5  6

b
  7  8  9
 10 11 12

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

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