2009-11-12 3 views
3

У меня есть основной вопрос о массиве и указателе в C/C++.массив указателей как параметр функции

Скажем, у меня есть:

Foo* fooPtrArray[4]; 

Как передать fooPtrArray в функцию? Я пробовал:

int getResult(Foo** fooPtrArray){} // failed 
int getResult(Foo* fooPtrArray[]){} // failed 

Как я могу иметь дело с массивом указателей?

EDIT: Я когда-то думал, что сообща ошибка от проезжающего неправильного массива указателей, но из всех ответов, я понимаю, что это что-то другое ... (назначение указателя)

Error msg: 
Description Resource Path Location Type incompatible types in assignment of 
`Foo**' to `Foo*[4]' tryPointers.cpp tryPointers line 21 C/C++ Problem 

Я надеваю «Не понимаю, почему он говорит: Foo * * to Foo * [4]. Если в качестве параметра функции они меняются друг с другом, почему во время назначения это дает мне ошибку компиляции?

Я пытался дублировать Сообщ ошибки с минимальным кодом следующим образом:

#include <iostream> 

using namespace std; 

struct Foo 
{ 
int id; 
}; 

void getResult(Foo** fooPtrArray) 
{ 
cout << "I am in getResult" << endl; 
Foo* fooPtrArray1[4]; 
fooPtrArray1 = fooPtrArray; 
} 

int main() 
{ 
Foo* fooPtrArray[4]; 
getResult(fooPtrArray); 
} 
+0

Определить «не удалось». Ошибка при компиляции? во время выполнения? как, точно (или смутно, я не против)? –

+0

Прилагаю мой код подстрижен, как указано выше, это ошибка времени компиляции. Ошибка возникает из функции void getResult (Foo * * fooPtrArray) – Lily

ответ

10

Оба

int getResult(Foo** fooPtrArray) 

и

int getResult(Foo* fooPtrArray[]) 

, а также

int getResult(Foo* fooPtrArray[4]) 

будет работать отлично (все они эквивалентны).

Непонятно из вашего вопроса, в чем была проблема. Что «не удалось»?

При прохождении массивов, как, что он обычно имеет смысл передать элемент рассчитывать, а также, поскольку трик с позволяя тип массива для declay к типу указателя обычно используется специально, чтобы позволить передачи массивов различных размеров

int getResult(Foo* fooPtrArray[], unsigned n); 
... 
Foo* array3[3]; 
Foo* array5[5]; 
getResult(array3, 3); 
getResult(array5, 5); 

Но если вы всегда будете передавать массивы строго 4 элементов, это может быть лучшей идея использовать по-разному типизированный указатель в качестве параметра

int getResult(Foo* (*fooPtrArray)[4]) 

в последнем случае вызова функции loook следующий

Foo* array[4]; 
getResult(&array); 

(обратите внимание на оператор &, примененный к объекту массива).

И, наконец, так как этот вопрос помечается как C++, в последнем случае ссылка может также использоваться вместо указателя

int getResult(Foo* (&fooPtrArray)[4]); 
... 
Foo* array[4]; 
getResult(array); 
+0

Это выглядит интересно: 'int getResult (Foo * (* fooPtrArray) [4])' с двумя звездочками и одной парой кронштейнов. Это верно? – ndim

+0

Да, это правильно. Но в C++ ссылка (вместо указателя) может быть более подходящей в этом случае (см. Комментарии adidtional в ответе). – AnT

+0

Можете ли вы подробно рассказать о том, как 'Foo * (& fooPtrArray) [4]' получает синтаксический анализ и как вы вызываете fooPtrArray из тела функции? – int3

0

Обе эти функции подписи выглядят, как они должны работать.При вызове функции, вы могли бы сделать что-то вроде этого:

int returnValue; 
returnValue = getResult(fooPtrArray); 
2

Что вы объявили со следующей строкой:

Foo* fooPtrArray[4]; 

является массивом указателей на Foo объектов (другими словами массивом Foo*).

В C/C++ имя массива определяется как указатель на начало массива. Это связано с тем, что массивы не являются «реальными» типами на этих языках, а просто непрерывной последовательностью значений определенного типа в памяти.

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

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

int getResult(Foo** fooPtrArray, int arraySize); 

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

for (int i=0; i < arraySize; i++) 
{ 
    Foo* fooPtr = fooPtrArray[i]; 
    if (fooPtr) 
    { 
     fooPtr->memberFunction(); 
     fooPtr->memberVariable; 
    } 
} 
0

Я не вижу, как это может скомпилировать без междунаров возвращенных?!

@ Kinopiko ваш код не компилируется на C++.

@ Лили, что вы получаете сообщение об ошибке? в вашем примере getResult должен возвращать int. Вероятно, это не так.

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