2

これを理解するのを手伝ってくれませんか。

「 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***)’

助けてくれてありがとう。

4

1 に答える 1

4

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です。

于 2012-12-21T23:59:48.590 に答える