Achar***
は「charへのポインターへのポインターへのポインター」です。配列はまったく関係ありません。あなたargv
は「charへの2つのポインタの配列」です。配列の名前 は、argv
特定の状況でその最初の要素へのポインターに減衰します。このポインターの型char**
は 、または「char へのポインターへのポインター」になります。
すると、 、または「charへの2つのポインターの配列へのポインター」&argv
が得られます。char* (*)[2]
これはあなたが望むものではありません。これは、ポインターではなく配列のアドレスを取得しているためです。
また、ポインターがnull で終わる文字列ではなく、argv
単一の s を指しているという事実に問題が生じるでしょう。ほとんどの場合、null で終わる文字列が期待されます。char
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
s が非 const である必要があるためですが、char* str = "hello";
スタイル宣言は非推奨です - でなければなりませんconst char*
。ただし、配列を使用すると、文字列リテラルの内容が配列にコピーされるため、自由に non- にすることができます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
toのパラメーターを渡さないことには正当な言い訳が必要gtk_init
です。