Могу ли я сделать это без указателей?
По крайней мере, вы можете избежать явного определения указателей, выполнив это следующим образом:
Определите тип матрицы 2D int
:
typedef int M[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]);
}
}