2012-12-21 3 views
2

не могли бы вы помочь мне понять это.Указатели и массивы Cpp

У меня есть функция, которая нуждается в "char *** argv";

Насколько я понимаю, это: указатель на указатель на массив указателей char.

что-то вроде этого: "char * arr []"?

char xx1 = '1'; 
char xx2 = '2'; 
char *argv[] = {&xx1,&xx2}; 

Тогда я называю функцию с gtk_init (& ARGC, & ARGV);

И получаю ошибку:

main.cpp:43:31: error: cannot convert ‘char* (*)[2]’ to ‘char***’ for argument ‘2’ to ‘void gtk_init(int*, char***)’ 

Спасибо за любую помощь.

+0

Закрыть. 'char * arr []' является указателем на массив, а не указателем на указатель на массив. –

+0

заменить каждый '*' на 'указатель на'. затем добавьте самый левый тип. –

+0

*** argv - это указатель на указатель на указатель, который в зависимости от того, что находится в этих указателях, может быть синонимом трехмерного массива. – RonaldBarzell

ответ

4

A char*** является «указателем на указатель на указатель на символ». Никаких массивов вообще. Ваш argv является «массивом из 2 указателей на символ». Имя вашего массива, argv, будет разлагаться на указатель на его первый элемент при определенных обстоятельствах - этот указатель будет иметь тип char** или «указатель на указатель на символ».

Когда вы делаете &argv, вы получаете char* (*)[2] или «указатель на массив из 2 указателей на символ». Это не то, что вы хотите. Это потому, что вы берете адрес массива, а не указателя.

Кроме того, у вас возникнет проблема с тем, что вы указатели в argv просто указывают на одиночные char s, а не на строки с нулевым завершением. gtk_init почти наверняка будет ожидать строки с нулевым завершением.

Итак, что вы можете сделать? Попробуйте это:

char xx1[] = "1"; // Now these are null-terminated strings 
char xx2[] = "2"; 
char* argv[] = {xx1, xx2}; 
char** argvp = argv; // Use the fact that the array will decay 
gtk_init(&argc, &argv); // &argv will now be a char*** 

Причина использование массивов для строк, потому что нам нужно char с, чтобы быть неконстантными, но декларация пространство char* str = "hello"; стиля устарела - он должен быть const char*. Однако, используя массивы, содержимое строкового литерала копируется в наш массив, поэтому мы можем свободно сделать его не const.

gtk_init действительно просто ожидает, что вы пройти argc и argv параметры вашей основной функции к ней, как так:

int main(int argc, char* argv[]) 
{ 
    gtk_init(&argc, &argv); 
    // ... 
} 

Теперь вы можете спросить: «Но почему &argv теперь разрешено argv того же типа, как в вопросе! Почему бы нам не получить указатель на массив снова? " На самом деле, argv - это не тот же тип, несмотря на то, насколько он похож. Когда вы определяете функцию, которая принимает аргумент массива, она фактически преобразуется в указатель. Таким образом, определение main эквивалентно:

int main(int argc, char** argv); 

Так что, когда мы делаем &argv, мы совершенно нормально, потому что это дает нам char***.

Как @OmnipotentEntity говорит в комментариях - вам лучше иметь хороший повод для того, чтобы не передавать параметры main в gtk_init.

+2

Следует также отметить, что 'gtk_init' предназначен для использования ваших аргументов' argc' и 'argv', поэтому, если вы не делаете что-то особенное или странное, вы, вероятно, должны просто передать их. – OmnipotentEntity

+0

@OmnipotentEntity Ваш комментарий заслуживает внимания. :) Edit: На самом деле, я его отредактирую. –

+0

Да, я делаю странные вещи. Попытка использовать GTK из Haxe, поэтому я привязываю некоторые функции haxe к cpp. Спасибо, это сработало. – somerandomusername

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