質問で引用されているように、C11標準では、argc
とargv
という変数と、argv
の配列が指す文字列が変更可能であることが明示的に記載されています。これらのポインタが変更可能であるかどうかは、手元の問題です。標準は明示的にそれを一方向または他の方法で述べていないようです。
2つのキーポイントは、標準で言葉遣いについて注意することがあります。
ポインタが不変であることをなっていた場合は、標準は、int main(int argc, char *const argv[])
として宣言することが主な要求することにより、それは明らかにされている可能性がこの質問に対する別の回答ではhaccks mentionedとなります。
argv
に関連して言及されたconst
であるという事実は意図的であると思われる。つまり、const
の欠如はオプションではありませんが、標準によって決定されます。
標準では、常にargv
が配列を呼び出します。配列の変更とは、メンバの変更を指します。したがって、標準の文言は、argv
が変更可能であると述べたときにargv
配列内のメンバーを変更することを意味することは明らかです。
一方、(C11ドラフトN1570、§6.7.6.3p7に基づいて)C の配列パラメータは「と 『入力する修飾ポインタ』に調整しなければなりません」。 x
とy
は、それぞれ、int *x
とint *y
に調整されているのでこのように、次のコード、
int foo(int x[2], int y[2])
{
if (x[0] > y[0])
x = y;
return x[1];
}
は、有効C11です。 (これはまた、C11ドラフトN1570、§6.3.2.1p3:"...配列で繰り返されています...「...配列の最初の要素を指すことを「型へのポインタ」型の表現に変換される。) もちろん、同じことは、ローカルまたはグローバル配列として宣言されていないしx
とy
場合、ではないであろうそれは、ポインタがあまりにも修正する必要があります。したがって、答えとして意味が関数のパラメータ。
は限り言語lawyerismが行くように、私は、標準はそれを一つの方法または別のを述べていないと言うだろう〜OP:両方。
実際には、argv
配列内のポインタの変更可能な伝統は非常に長いです。多くのライブラリには、argc
へのポインタとargv
配列へのポインタを取る初期化関数があり、そのうちのいくつかはargv
配列のポインタを変更します(ライブラリ固有のオプションを削除します)。例えばGTK+ gtk_init()
とMPI_Init()
です(少なくともOpenMPIでは明示的にそれを調べたり変更しないと明言していますが)。パラメータ宣言(int *argc, char ***argv)
を探します。唯一の理由は、を使用してmain()
から呼び出すことを意図している場合は、ポインタを変更して、ライブラリ固有のコマンドラインパラメータを解析してコマンドラインパラメータから削除し、argc
とポインタは必要に応じてargv
にあります。
(私はもともとPOSIX でgetopt()
施設は変更可能で、ポインタにを依存していると述べている - ほとんどのUnixのフレーバーで採択されたバック1980年にさかのぼる機能を、そして1997年にPOSIX.2で標準化 - しかし、それはありますジョナサン・レフラーはコメントで指摘したように、誤っ、:;だけGNU getopt()
はありません、それはPOSIXLY_CORRECT
環境変数が設定されていない場合にのみ、両方GNU getopt_long()
とBSDはgetopt_long()
ポインタを変更POSIXLY_CORRECT
が設定されていない限り、POSIX getopt()
は、実際のポインタを変更しません。しかし、それらはgetopt()
と比較してはるかに若く、広範ではない。
Unixの土地では、argv[]
配列、が指す文字列の内容を変更し、変更された文字列がプロセスリストに表示されるように、 "移植可能"とみなされました。これがどのように役立つかの一例は、DJBのdaemontoolsパッケージreadproctitleです。 (文字列はインプレースで変更する必要があり、変更をプロセスリストに表示するには拡張できません)。
これは、C言語の誕生以来、プログラミング言語として、Cの標準化に先立ち、argc
,argv
、argv
配列のポインタ、およびこれらのポインタが指す文字列の内容を変更可能なものとして扱うことができます。
C標準の目的は、新しい動作を定義するのではなく、(移植性と信頼性を促進するために)既存の動作をコード化しているためです。 argv
配列内のポインタを変更可能として明示的に指定しないようにすることができます。それ以外のものは伝統を破り、POSIX規格(システム間の移植性を促進することを目的としており、ISO C標準には含まれていないCの機能を拡張することを意図している)とは明らかに反するでしょう。
'argv'は変更可能であり、' argv'はあなたが話すポインタを含んでいます。 –
@SimonShineしかし、 'argv'が変更可能な場合、' argv = ... 'のみが実行可能であり、必ずしも' * argv = ... 'ではないという意味ですか? – Downvoter
適切な 'main'関数宣言の1つが' int main(int argc、char * argv []) 'であるため、' argv'パラメータは 'char *'ポインタではなく 'char * argv [] 'ポインタ。したがって、文字列は変更可能です。 – nsilent22