5

重複の可能性:
main の argc と argv

一般的な main 関数の宣言に使用される表記法、つまりint main(int argc, char *argv[]). 実際に main 関数に渡されるのは へのポインタへのポインタであることは理解していますがchar、表記が難しいと思います。例えば:

**argv文字列全体ではなく、最初の文字を指すのはなぜですか? 同様に、Why does*argv[0]は前の例と同じものを指しています。

前の例のよう*argvに最初の文字列ではなく、最初の文字列全体を指すのはなぜですか?char

これは少し無関係ですが*argv + 1、配列内の次の文字列を指すのではなく、「最初の文字を引いた」文字列を指すのはなぜですか?

4

4 に答える 4

11

を使ったプログラムを考えてみましょうargc == 3

   argv
     |
     v
+---------+         +----------------+
| argv[0] |-------->| program name\0 |
+---------+         +-------------+--+
| argv[1] |-------->| argument1\0 |
+---------+         +-------------+
| argv[2] |-------->| argument2\0 |
+---------+         +-------------+
|    0    |
+---------+

変数argvは、ポインターの配列の先頭を指します。 argv[0]最初のポインターです。プログラム名を指します (または、システムがプログラム名を判別できない場合、文字列 forargv[0]は空の文字列になります; argv[0][0] == '\0')。 argv[1]は最初の引数をargv[2]指し、2 番目の引数を指し、argv[3] == 0(同等にargv[argc] == 0) を指します。

もちろん、知っておく必要があるその他の詳細は、array[i] == *(array + i)任意の配列に関するものです。

あなたは具体的に尋ねます:

  • **argv が文字列全体ではなく最初の文字を指すのはなぜですか?

*argvは に相当し*(argv + 0)、したがってargv[0]. ですchar *。a を逆参照するchar *と、文字列の「最初の」文字が取得されます。したがって、 andはまたはまたは**argvと同等です。*(argv[0])*(argv[0] + 0)argv[0][0]

(これはポインターではなく文字であると正当に主張できる**argvため、「最初の文字を指す」わけではありません。単に of の別の名前です'p'"program name\0")

  • 同様に、なぜ *argv[0] は前の例と同じものを指すのでしょうか。

前に述べたように、argv[0]は文字列へのポインタです。したがって*argv[0]、文字列の最初の文字にする必要があります。

  • *argv前の例のように最初の文字ではなく、最初の文字列全体を指すのはなぜですか?

これは慣例の問題です。 *argv最初の文字列の最初の文字を指します。文字列へのポインターとして解釈すると、「文字列全体」を指すのと同じように、「char *pqr = "Hello world\n";文字列全体」を指します。これを単一の文字へのポインタとして解釈すると、文字列の最初の文字を指します。波動と粒子の二重性と考えてください。ここだけ文字列の二重性です。

  • *argv + 1配列内の次の文字列を指すのではなく、「最初の文字を引いた」文字列を指すのはなぜですか?

*argv + 1です(*argv) + 1。すでに説明したように*argv、 は最初の文字列の最初の文字を指します。ポインターに 1 を追加すると、次の項目を指します。*argv文字を指すので、次の文字を指し*argv+1ます。

*(argv + 1)次の文字列 (の最初の文字) を指します。

于 2012-11-13T15:30:47.683 に答える
3

それはすべてポインタ演算に落ちます。

*argv[0] = *(*(argv + 0)) = **argv

since[]は unary よりも優先され*ます。

一方、*argvポインタを含む配列である配列の最初のセルを指定します。このポインターは何を指していますか? もちろん、なぜchar配列、文字列なのか。

*argv + 1+unary よりも優先順位が低いため*、最初に文字列へのポインターを取得し、それに 1 を追加して、文字列の 2 番目の文字のポインターを取得します。

于 2012-11-13T15:18:26.620 に答える
2

I understand that what is actually passed to the main function is a pointer to a pointer to char

いいえ、渡されるのはcharポインタの配列(文字列の配列)です。コマンドプロンプトでこれを指定すると、次のように考えられます。

>> ./program hello 456

私のプログラムのメインは次のようになります。

argc == 3

argv[0] == program (the name of the program as a string)
argv[1] == hello   (the first parameter as a string)
argv[2] == 456     (the second parameter as a string)

Why does **argv point to the first char and not the whole string?

char *argv[]  //an array of character pointers
*argv         // an array decays to a pointer, so this is functionally equivalent to
              // argv[0]
**argv        // Now the argv[0] decays to a pointer and this is functionally
              // equivalent to (argv[0])[0]

Likewise, why does *argv[0] point to the same thing as the previous example.

上記を参照。

Why does *argv point to the whole first string, instead of the first char like the previous example?

上記を参照。

于 2012-11-13T15:34:17.113 に答える
-1

これはすべて、配列が c の配列の最初の要素へのポインターでもあるためです。 **argvchar へのポインターへのポインターを 2 回逆参照して、char を取得します。 *argv[0]は基本的に「そのアドレスを逆参照し、逆参照から取得したばかりのアドレスで記述された配列の最初の要素を返す」と言っていますが、これはたまたま同じことです。 *argv逆参照は 1 回だけなので、char へのポインター、または char 配列がまだ残っています。 *argv + 1逆参照を 1 回行って最初の文字列を取得し、アドレスに 1 を追加して 2 番目の要素のアドレスを取得します。*argvポインターも配列であるため、これは配列から最初の要素を引いたもの であると言えます。

于 2012-11-13T15:19:52.973 に答える