Ссылка на еще не упомянутый параметр функции с помощью объявлений функций нового стиля - PullRequest
1 голос
/ 28 марта 2019

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

void print_matrix(M, dim)
     unsigned dim;
     int M[dim][dim];
{
    /* Print the matrix here. */
    ...

Хорошая новость заключается в том, что код работает и имеет параметры в том порядке, в котором я хотел бы, чтобы они были.

Плохая новость заключается в том, что мне пришлось использовать синтаксис объявления функции "старого стиля", чтобы сослаться на еще не объявленный аргумент dim в объявлении M, которое, очевидно, считается устарел и опасен .

Есть ли прямой способ сделать то же самое с объявлениями функций "нового стиля" БЕЗ изменения порядка параметров? (А если нет, то считается ли приемлемым использование синтаксиса старого стиля в данной конкретной ситуации?)

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

В портативном (стандартном) C вы не можете делать то, что показываете.Вы должны указать размер перед матрицей.Оригинальный код в вопросе был:

void print_matrix(M, dim)
     unsigned dim;
     int (*M)[dim][dim];
{

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

void print_matrix(unsigned dim, int (*M)[dim][dim]);

Этопозволяет вызывать функцию с трехмерным массивом.Или с измененной нотацией в вопросе вы можете напечатать двумерный массив:

void print_matrix(unsigned dim, int M[dim][dim]);

GCC предоставляет расширение для помощи.Цитирование руководства:

Если вы хотите сначала передать массив, а потом длину, вы можете использовать прямое объявление в списке параметров - еще одно расширение GNU.

struct entry
tester (int len; char data[len][len], int len)
{
  /* … */
}

Вы можете написать любое количество таких предварительных объявлений параметров в списке параметров.Они могут быть разделены запятыми или точками с запятой, но последняя должна заканчиваться точкой с запятой, за которой следуют «реальные» объявления параметров.Каждое прямое объявление должно соответствовать «реальному» объявлению в имени параметра и типе данных.ISO C99 не поддерживает предварительные объявления параметров.

0 голосов
/ 11 апреля 2019

Объявление старого стиля, которому предшествует прототип, синтаксически некрасиво, но не более опасно, чем объявление нового стиля.

void print_matrix(int M[*][*], unsigned dim);
void print_matrix(M, dim)
     unsigned dim;
     int M[dim][dim];
{
  ...
}

Авторы Стандарта признали, что объявления старого стилябыли действительными, полезными и достаточными средствами для выполнения задачи, и решили, что написание правил, разрешающих с объявлениями нового стиля, будет слишком большой работой, поэтому они не хотели беспокоиться.Таким образом, сочетание прототипа и объявления старого стиля является единственным способом достижения соответствующей семантики.

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