argvの末尾に常にnullがあるのに、なぜargcが必要なのですか?


116

と思われるargv[argc]常にあるNULLので、私たちはせずに引数リストを横切ることができると思いますargc。単一のwhileループがこれを行います。

NULLの最後に常にaがある場合argv、なぜ必要なのargcですか?


17
それはおそらく便利さの問題です。十分な引数がない場合、ループせずにプログラマーが早期に救済できる簡単な方法を提供します。そうでなければ、きっとこれを実行する関数が確実に呼び出されます:int argc(char *argv[])
cnicutar 2013

5
ただ明確にすること"\0"は、NULLポインタと同じではありません(0C ++ではNULLと同等です)
Mats Petersson 2013

31
argcがある場合、なぜargv [argc]をNULLにする必要があるのですか?
Ambroz Bizjak 2013

7
他にどのようにして一定時間内の引数の数を決定しますか?
avakar 2013

4
この動作はすべてのオペレーティングシステムのすべてのコンパイラに当てはまるため、ここではlinux / unixタグが適切であるとは思わないでください。
Darrel Hoffman

回答:


106

はい、argv[argc]==NULL保証されています。C11 5.1.2.2.1プログラムの起動を参照(私の強調)

それらが宣言されている場合、メイン関数のパラメーターは次の制約に従います。

argcの値は負ではありません。 argv [argc]はnullポインターです。

argcしたがって、提供することは重要ではありませんが、それでも役立ちます。特に、正しい数の引数が渡されたことをすばやく確認できます。

編集:質問がC ++を含むように修正されました。n3337ドラフト3.6.1メイン関数は言う

2 ... argcは、プログラムが実行される環境からプログラムに渡される引数の数です。.... argcの値は負でない必要があります。argv [argc]の値は0です。


36
そして、argcシェル拡張を行っているので、(そうで、非常に大きな可能性が前にシェルによって展開されるの実行可能)。私のシステムでは、数十万のシステムを使用できます。ls **execve/bin/lsargc
Basile Starynkevitch 2013

それはかなりクールです、私は常にargc十分であると考えていたので、これは私には決して起こりませんでしたが、私はこの保証が関連し、さらには必要とされる状況を確実に考えることができます。+1
トーマス

6
@BasileStarynkevitchカウントを取得するために、ポインタ値の配列をNULLまで1回余分にステップするだけの時間は、ポインタ配列の生成に既に費やされた時間と比較して非常に小さく、プログラムで実際に各引数値を使用する場合と比較するとさらに重要ではありません。また、引数の数がNより大きいかどうかを確認するだけの場合、配列全体を調べる必要はありません。それでも、私は完全に同意しargcます。
hyde 2013

43

はい、argv[argc]nullポインタであることが保証されています。argc便宜上使用されます。

C99 Rationaleからの公式説明を引用して、冗長チェックという言葉に注意してください

国際標準の根拠—プログラミング言語— C§5.1.2.2.1 プログラムの起動

の仕様argcおよびそのargvための引数として、main広範囲にわたる従来の慣行を認識しています。argv[argc]これも一般的な慣行に基づいて、リストの最後の冗長チェックを提供するには、ヌルポインターである必要があります。


19

歴史的な理由と古いコードとの互換性のためです。元々、argv配列の最後の要素としてnullポインターが存在するという保証はありませんでした。しかし、argcは常に存在しています。


...それはある意味で残念です。があった場合int main(char *argv[], int argc, ...)、一部のプログラムはargcそれを必要としないため、省略できます。反対(必要argcではないがargv)は、実際のプログラムではおそらく役に立たないでしょう。
hyde 2013

@hyde:上記のBasile Starynkevitchのコメントを参照してください
zentrunix

6

さまざまな規格で要求されているため、「必要」です。

値は完全に無視できますが、これはの最初のパラメーターであるmainため、パラメーターリストに含める必要があります。C ++(およびおそらく非標準のC方言)では、次のC ++スニペット(Cへの変換が簡単)のように、パラメーター名を省略できます。

#include <stdio.h> // C-compatible include, guarantees puts in global namespace

// program will print contents of argv, one item per line, starting from argv[0]

int main(int /*argc*/, char *argv[]) { // uncomment argc for C

    //(void)argc; // uncomment statement for C

    for (int i=0; argv[i]; ++i) {
        puts(argv[i]);
    }

    return 0;
}

標準Cでは、一般的な警告設定で、未使用のパラメーターが警告(void)argc;を生成します。これは、コードを生成せずに名前が使用されるようにするステートメントによって修正できます。

argcそれ以外の場合、多くのプログラムは、カウントを取得するためにパラメータを徹底的に調査する必要があるためです。また、長さのある配列を持つ多くのプログラミング言語では、argcパラメーターはなく、項目を持つ配列しかありません。


問題は、CとC ++の両方についてです。Cでは、パラメーター名は必須です。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.