2010-11-11 2 views
0

У меня есть 2D массив указательПередача 2D массив указатель на функцию C

main.c 

Int32 * pRxSeqAddr[2][2]; 

func(pRxSeqAddr); 

/

func.c 

void func(Int32** pRxSeqAddrPtr) 
{ 

/// 
} 

Я получаю эту ошибку:

argument of type "Int32 *(*)[2]" is incompatible with parameter of type "Int32 ** 

Я знаю, что если бы это было 1D, тогда этот вызов функции прекрасен, но 2D меня ныряет.

пожалуйста, помогите

ответ

5

Изменить func.c на:

void func(Int32 *pRxSeqAddrPtr[][2]) 
{ 

} 

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

void func(Int32 *pRxSeqAddrPtr[2][2]) 
{ 

} 

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

+0

Привет, Пол, спасибо, это работает ... но я не знаю, как интерпретировать логику этого. – user437777

+0

@ user437777: ОК - Я добавил немного больше разъяснений - HTH –

+0

Привет, Пол, спасибо за разъяснение. .. Я проверил значения, которые он прошел внутри функции. Он правильно передал мне адреса 1-го и 2-го столбцов. Чтобы получить адреса строк, мне нужно вручную извлечь с помощью somekind смещения указателя? – user437777

-3

В C по умолчанию 2D array'' are массив указателей на 1D массивы ''.

Итак, вы должны назвать тип: Int32 ***

Первой звездой для первого измерения массива. (массивы являются указателями на их первый элемент) Вторая звезда для измерения второго массива. (указатели на первый элемент строки) Третья звезда, потому что элементы являются указателями.

+0

Сохранены в виде массива 1D. – ruslik

-2

Это, безусловно, работать:

Int32* pRxSeqAddr[2*2]; 
func(pRxSeqAddr); 

void func(Int32** pRxSeqAddrPtr){}; 

Или в исходном примере, можно вызвать функцию с

funct(&pRxSeqAddr[0][0]); 
+0

Он может «работать», но на самом деле он не отвечает на вопрос, поскольку он просто избегает проблемы с передачей 2D-массивов. –

+1

Изменение типа массива, а не исправление параметра, кажется неправильным путем. –

+0

@Paul R в вашем случае функция becames заблокирована размером '[2]'. Может быть, OP просто нужен простой простой указатель в функции? – ruslik

4

исключением случаев, когда это операнд из sizeof или одинарных & операторов или является строковым литералом, используемым для инициализации другого массива, выражение типа типа «N-элементный массив из T» будет неявно преобразован («распад»), чтобы ввести «указатель на T», а его значение будет адрес первого элемента массива.

Когда вы делаете вызов func(pRxSeqAddress), тип выражения pRxSeqAddress преобразуются из «2-элементного массива 2-элементного массива указателя Int32» в «указатель на 2-элементный массив указателей на Int32», или Int32 *(*)[2]. Таким образом, прототип func должен быть

void func(Int32 *(*pRxSeqAddressPtr)[2]) { ... } 

В контексте описания параметра функции, T a[] и T a[N] являются синонимом T *a; a на самом деле имеет тип указателя, а не тип массива. Таким образом, вышеизложенное можно было бы переписать как

void func(Int32 *pRxSeqAddressPtr[][2]) { ... } 

, который выглядит немного чище, чем указатель на синтаксис массива; однако я предпочитаю первое, поскольку он точно описывает, что происходит.Обратите внимание, что это только true в контексте объявления параметра функции.

Так что, учитывая заявление T a[N][M];, следующий все справедливы

 
Expression  Type   Decays to 
----------  ----   --------- 
     a  T [N][M]  T (*)[M] 
     &a  T (*)[N][M] n/a 
     *a  T [M]  T * 
     a[i]  T [M]  T * 
    &a[i]  T (*)[M]  n/a 
    *a[i]  T   n/a 
    a[i][j]  T   n/a 

Обратите внимание, что это тип выражения со ссылкой на массив, что изменения, а не сам массив; Объект pRxSeqAddr, определенный в main, всегда и всегда имеет тип массива.

+0

спасибо, Джон ... приятно объяснил .. я уверен, что это поможет многим ... – user437777