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