Инициализация 2D массива в C - PullRequest
4 голосов
/ 10 декабря 2010

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

static int A[3][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };

Это нормально, и я могу получить доступ ко всем членам этого. Однако у меня есть несколько проблем с передачей его функции, например ::1004*

void print_matrix(int **a, int r, int c)
{
    int x, y;

    for(x = 0; x < r; x++)
    {
        printf("Row %02d = %#x = ", x, a[x]);

        for(y = 0; y < c; y++)
        {
            printf("%s%d", (0 == y) ? "" : ", ", a[x][y]);
        }
        printf("\n");
    }
}

Во-первых, я не могу просто передать A в функцию, мне нужно привести ее к (int **). Поскольку char * является синонимом char [], я был немного удивлен этим. Во-вторых, происходит сбой, и когда я проверяю в отладчике внутри подфункции, a[0] сообщается как 1, а не как указатель на массив целых чисел.

Я знаю, что здесь происходит тайная магия языка компилятора / Си. Но все это немного сбивает с толку. Если я попытаюсь инициализировать как:

static int *A[3] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };

Я получаю массу предупреждений. Как это отличается от:

static char *S[3] = { "hello", "there", "stackoverflow" };

Помимо вопроса о тайной магии C, которую я так или иначе никогда не изучал, несмотря на более чем десятилетнее программирование на C :(, я хотел бы знать, как генерировать мой массив, чтобы я мог успешно передать его как int ** без необходимость пройти через все помехи для циклов for или скопировать статически размещенный массив в динамически распределенный.

Будет ли работать следующее?

int *A0 = { 1, 2 };
int *A1 = { 3, 4 };
int *A2 = { 5, 6 };
int **A = { A0, A1, A2 };

Есть ли лучший способ сделать это?

Спасибо всем.

P.s. Я знаю, что в реальной жизни мы читали бы значения из БД или файла в динамически распределяемые массивы и избегали всего этого.

Ответы [ 5 ]

10 голосов
/ 10 декабря 2010

Многомерный массив не становится многоуровневым указателем (я не знаю правильного термина). Разлагается только одно измерение. Например:

int [20] становится int *; int [20][5] становится int (*)[5] (что не int **); и т.д.

Если есть большое желание использовать многомерные массивы (с помощью синтаксиса [r][c]), тогда вам нужно пройти другие границы (которые должны быть константами). Если требуются переменные границы, я думаю, что лучшим вариантом будет выполнить преобразование индекса вручную (то есть вместо a[r][c], используйте a[r*C + c]).

2 голосов
/ 27 сентября 2016
int A0[2] = { 1, 2 };
int A1[2] = { 3, 4 };
int A2[2] = { 5, 6 };
int *A[3] = { A0, A1, A2 };

Вы были близки с последним разделом, но вам нужно немного другое объявление.Полученный A можно передать как int ** в функцию.

При этом print_matrix(A, 3, 2); выдает:

Row 00 = 0x5eaeda70 = 1, 2
Row 01 = 0x5eaeda68 = 3, 4
Row 02 = 0x5eaeda60 = 5, 6
2 голосов
/ 10 декабря 2010

Я бы начал с консультации на этот вопрос в FAQ C * , за которым следует весь раздел .

1 голос
/ 10 декабря 2010

Самый быстрый способ - объявить аргумент a как int a[][2].

void print_matrix(int[][2] a, int r, int c);

// and call the function like this:
print_matrix(A, 3, 2);
0 голосов
/ 10 декабря 2010
static char *S[3] = { "hello". "there", "stackoverflow" };
                          // ^~~~~~ This is a period.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...