Несовместимый массив типов указателей на указатели

c arrays pointers

652 просмотра

3 ответа

У меня проблема с типами указателей. Компилятор GCC выдает следующее предупреждение:

416:31: warning: passing argument 1 of 'locateInHWNDArray' from 
    incompatible pointer type [-Wincompatible-pointer-types]
         locateInHWNDArray(hWndLWTxt, (HWND)lParam, &x, &y);
                           ^
foodplaner.c:76:6: note: expected 'struct HWND__ ***'
but argument is of type 'struct HWND__ * (*)[4]'
void locateInHWNDArray(HWND **array, HWND el, int *x, int *y);
     ^

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

void locateInHWNDArray(HWND **array, HWND el, int *x, int *y)

и вызов следующий

locateInHWNDArray(hWndTWTxt, (HWND)lParam, &x, &y);

с hWndTwTxt объявлен как

HWND hWndTWTxt[7][4];

Я предполагаю, что это связано с объявлением определенного размера, но я понятия не имею, чего именно хочет компилятор.

Автор: Doopy Источник Размещён: 08.11.2019 11:27

Ответы (3)


2 плюса

Решение

Проблема в том, что двумерный массив и указатель на указатель - это не одно и то же.

foodplaner.c: 76: 6: примечание: ожидается «struct HWND__ ***», но аргумент имеет тип «struct HWND__ * (*) [4]»

Первая часть этого сообщения об ошибке (перед «но») просто означает, что HWNDэто эквивалентно HWND__ * (где HWND__тип определен в заголовочном файле, включенном в ваш проект).

Вторая часть сообщения об ошибке (после «но») говорит вам, hWndTwTxtчто передается как указатель на массив 4 HWND__ *. Это согласуется - двумерный массив измерений [7][4]передается как указатель на массив 4элементов.

В сочетании, сообщение об ошибке говорит вам, что 2D-массив не может быть преобразован в указатель на указатель.

Предполагая, что вашей функции нужно передать что-то похожее на 2D-массив, вам нужно либо указать свою функцию как

void locateInHWNDArray(HWND array[7][4], HWND el, int *x, int *y)

или как

void locateInHWNDArray(HWND (*array)[4], HWND el, int *x, int *y)

Любой из них основывается на том, что второе (самое правое) измерение (т.е. 4) известно во время компиляции. В любом случае, функция должна использовать допустимые индексы массива (то есть, когда вы что-то делаете с array[i][j], iдолжны быть между 0и 7и jдолжны быть между 0и 4).

Если вы действительно хотите передать HWND **(то есть, не изменяя типы аргументов функции), вам нужно сделать что-то вроде этого

HWND **temp;
int i, j;
temp = malloc(7*sizeof(*temp));
for (i = 0; i < 7; ++i)
{
    temp[i] = malloc(4*sizeof(*temp[i]));
    for (j = 0; j < 4; ++j)
        temp[i][j] = hWndTWText[i][j];
}

locateInHWNDArray(temp, (HWND)lParam, &x, &y);

/* copy from temp back to `hWndTWText` if the function modifies elements */

for (int i = 0; i < 7; ++i)
    free(temp[i]);
free(temp);

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

Автор: Peter Размещён: 20.08.2016 03:29

2 плюса

Массив HWND ** ожидает массив указателей, а не двумерный массив. Вы можете объявить это как:

HWND* hWndTWTxt[n]

Затем вы должны создать каждый указатель в массиве индивидуально.

Смотрите этот ответ для более подробного объяснения:

https://stackoverflow.com/a/16724679/6726446

Автор: js441 Размещён: 20.08.2016 03:16

0 плюса

Вот что вам нужно .

Короче говоря, вам нужно передать число измерений в качестве указателей, но поскольку у вас есть статический массив (а статический 2D-массив требует, чтобы указатели второго уровня указывали constна статический массив), это будет работать:

void locateInHWNDArray(HWND array[7][4], HWND el, int *x, int *y)

Или используйте любой из способов, перечисленных в связанном ответе.

Автор: smrdo_prdo Размещён: 20.08.2016 02:54
32x32