Компилятор предупреждает о несоответствующих объявлениях функций, связанных с массивами

#c #arrays

#c #массивы

Вопрос:

Я пытаюсь написать функцию, которая принимает массив в качестве параметра. Однако компилятор C (lcc) выдает предупреждение (т. Е. мой файл все еще компилируется) о том, что «.tetris.c: 179: предупреждение: объявление `clear_array’ не соответствует предыдущему объявлению в .tetris.c: 172».

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

 void remove_filled_rows ()
{
    int row;
    for (row = 0; row < NROWS; row  ) {
        // [snip] 
        if (col == NCOLS) {
            clear_array (cells[row]);    // line 172
        }
    }

}

/* Helper method that clears a row */
void clear_array (lc4uint row_array[]) {    // line 179
    int col;
    for (col = 0; col < NCOLS; col  ) {
        row_array[col] = 0;
    }
}
  

Мой массив объявлен следующим образом:

 lc4uint cells[NROWS][NCOLS];
  

где NROWS и NCOLS являются целочисленными константами, а lc4uint это просто typedef для unsigned int .

Ответ №1:

Объявление должно предшествовать доступу. Либо переместите clear_array в перед вызовом, либо добавьте прототип для clear_array функции перед вызовом. Вы должны были получить ошибку / предупреждение об этом в любом приличном компиляторе.

Отдача — строка 172 не должна была быть объявлением, строка 179 была. Но в ошибке говорилось, что 172 было объявлением.

Комментарии:

1. Сообщение @GiantMarshmallow gcc может быть немного более полезным, в нем говорится о предыдущем неявном объявлении. Используя его перед объявлением, вы неявно объявляете его (с возвращаемым типом int).

Ответ №2:

 lc4uint cells[NROWS][NCOLS]; // == lc4uint cells[NROWS*NCOLS] 
  

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

 fun(lc4uint cells[][NCOLS]);
  

поскольку тип ячеек

 lc4uint *
  

таким образом, in clear_array (cells[row]) ; cells[row] является одним элементом и имеет тип lc4uint , следовательно, нет совпадающих типов объявлений функций. Поскольку до этого момента объявление не было дано, компилятор предполагает, что теперь:
clear_array(lc4uint) в то время как вы интересовались clear_array(lc4uint *)

Вы должны изменить свое объявление массива на что-то вроде

 lc4uint **cells = (lc4uint**) calloc(NROWS, sizeof(lc4uint*));
lc4uint *tmp = (lc4uint *) calloc(NROWS*NCOLS, sizeof(lc4uint))
for(int i = 0; i < NROWS; i  ) cells[i] = amp;(tmp[i*NCOLS])
  

в противном случае cells[row] не возвращает указатель на правильную строку.