Как создать статический массив матрицы - PullRequest
0 голосов
/ 19 мая 2019

У меня проблема с C.

Я должен создать статический массив tmp из 4 элементов, и для всех ячеек этого массива я должен хранить матрицу 2x2.

Могу ли я сделать это без указателей?

Я пытался с int[2][2] tmp[4], но у меня была ошибка компиляции.

1 Ответ

3 голосов
/ 19 мая 2019

Могу ли я сделать это без указателей?

По крайней мере, вы можете избежать явного определения указателей, выполнив это следующим образом:

  1. Определите тип матрицы 2D int:

    typedef int M[2][2];
    
  2. Определите тип массива 1D последнего:

    typedef M A[4];
    

Пример использования этих типов может выглядеть следующим образом:

#include <stdio.h>

#define MATRIX_ROWS (2)
#define MATRIX_COLUMNS (2)

typedef int M[MATRIX_ROWS][MATRIX_COLUMNS];

#define ARRAY_SIZE (4)

typedef M A[ARRAY_SIZE];

int matrix_set(M m)
{
  for (size_t i = 0; i < MATRIX_ROWS; ++i)
  {
    for (size_t j = 0; j < MATRIX_COLUMNS; ++j)
    {
      m[i][j] = (int) ((i+1)*(j+1));
    }
  }

  return 0;
}

int matrix_print(M m)
{
  for (size_t i = 0; i < MATRIX_ROWS; ++i)
  {
    for (size_t j = 0; j < MATRIX_COLUMNS; ++j)
    {
      printf("m[%zu][%zu] = %d\n", i, j, m[i][j]);
    }
  }

  return 0;
}

int main(void)
{
  A a;

  for (size_t i = 0; i < ARRAY_SIZE; ++i)
  {
    printf("setting a[%zu]:\n", i);
    matrix_set(a[i]);
  }

  for (size_t i = 0; i < ARRAY_SIZE; ++i)
  {
    printf("printing a[%zu]:\n", i);
    matrix_print(a[i]);
  }
}

Обратите внимание, что под капотом C использует здесь указатели, как это объявление функции:

int matrix_set(M m);

фактически является

int matrix_set(int m[2][2]);

, что эквивалентно

int matrix_set(int (*m)[2]);

Так что, хотя и не очевидно, m является указателем, а именноуказатель на массив 2 int, int(*)[2].

Кроме того, этот вызов

  matrix_set(a[i]);

передает переменную типа M, которая является массивом 2x2int, int[2][2], который на самом деле является массивом из 2 элементов массива типа 2 int, int[2].

Если в C массив передается функции, онраспадается на указатель на адрес его1-й элемент.

1-й элемент массива из 2 элементов типа массив 2 int - это массив 2 int.Указатель на последний имеет тип int(*)[2], который в точности соответствует типу указателя, которого ожидают две функции matrix_set() и matrix_print(), как уже объяснено выше.

Таким образом, альтернатива, возможно, более пуристическая, ноэквивалентный способ написать приведенный выше пример:

#include <stdio.h>

#define MATRIX_ROWS (2)
#define MATRIX_COLUMNS (2)

#define ARRAY_SIZE (4)

int matrix_set(int (*m)[MATRIX_COLUMNS])
{
  for (size_t i = 0; i < MATRIX_ROWS; ++i)
  {
    for (size_t j = 0; j < MATRIX_COLUMNS; ++j)
    {
      m[i][j] = (int) ((i+1)*(j+1));
    }
  }

  return 0;
}

int matrix_print(int (*m)[MATRIX_COLUMNS])
{
  for (size_t i = 0; i < MATRIX_ROWS; ++i)
  {
    for (size_t j = 0; j < MATRIX_COLUMNS; ++j)
    {
      printf("m[%zu][%zu] = %d\n", i, j, m[i][j]);
    }
  }

  return 0;
}

int main(void)
{
  int a[ARRAY_SIZE][MATRIX_ROWS][MATRIX_COLUMNS];

  for (size_t i = 0; i < ARRAY_SIZE; ++i)
  {
    printf("setting a[%zu]:\n", i);
    matrix_set(a[i]);
  }

  for (size_t i = 0; i < ARRAY_SIZE; ++i)
  {
    printf("printing a[%zu]:\n", i);
    matrix_print(a[i]);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...