2013-05-30 20 views
2

Это объявление функции, и компилятор дает: «ошибка: тип массива имеет неполный тип элемента» как в объявлении, так и в определении. Я не вижу ошибки.«Ошибка: тип массива имеет неполный тип элемента» в объявлении функции

void calculate(float matrM[][], int origMatr[][]); 
+1

Это декларация, определение более длинное с фигурными фигурными скобками. – user2384250

+0

Вам нужно указать размер первого размера: '(float matrM [3] [], int origMatr [3] [])' – Mifeng

ответ

5

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

Вы не можете объявить массив такого размера, вы должны указать все размеры, кроме одного, иначе нет способа вычислить адрес случайного элемента в массиве.

Это часто лучше разбить его, как:

void calculate(float *out, const float *in, size_t width, size_t height); 

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

out[y * width + x] = in[y * width + x]; 
+0

Это только при передаче двух массивов? Потому что 30 минут назад я передал массив без каких-либо параметров и 2 целых числа, и он не дал мне ошибку – Arlind

+0

ну, это зависит от того, что я не очень сильно использую C, но я помню «структурный взлом», который обычно выполняется для избегать такого распределения и получить какое-то «автоматическое и автоматическое» распределение, но это не совсем определенное поведение, оно скорее похоже на неопределенное поведение, поэтому его небезопасно принимать. – user2384250

+1

@Arlind Это при передаче массивов. В принципе, единственной информацией, которая отправляется функции во время выполнения, является адрес первого элемента. Вся остальная информация должна присутствовать в декларации, иначе индексирование становится невозможным. – unwind

5

ваш "внутренний" размеры должны иметь размер, например:

void calculate(float matrM[][5], int origMatr[][7]); 

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

Для получения дополнительной информации см. How do I write functions which accept two-dimensional arrays when the width is not known at compile time? из C FAQ.

1

Вы получаете только одно «свободное» измерение (первое), когда вы передаете массив функции. Правильная декларация будет выглядеть как:

void calculate(float matrM[][N], int origMatr[][M]); 
+0

'N' и' M' не должны быть константами, начиная с C 1999. –

4

Если у вас есть современный C компилятор (C99 будет делать), вы можете иметь «лишние» размеры как выражения других параметров функции, которые предшествуют

void calculate(size_t n, float matrM[][n], int origMatr[][n]); 

вам просто нужно быть осторожным, чтобы у вас были эквивалентные параметры в вашем объявлении (тот, который я дал) и определение (то, которое обеспечивает реализацию функции).

Смежные вопросы