2012-02-24 5 views
1
#include <stdio.h> 

main(argc, argv) 
int argc; 
char *argv[]; 
{ 
    register int i, nflg; 

    nflg = 0; 
    if(argc > 1 && argv[1][0] == '-' && argv[1][1] == 'n') { 
     nflg++; 
     argc--; 
     argv++;  //Incements a constant pointer, how??? 
    } 
    for(i=1; i<argc; i++) { 
     fputs(argv[i], stdout); 
     if (i < argc-1) 
      putchar(' '); 
    } 
    if(nflg == 0) 
     putchar('\n'); 
    exit(0); 
} 

このプログラムはargvの値をインクリメントしますが、argvはCの定数ポインタです。なぜこれからコンパイルエラーが発生しないのですか?V7エコープログラムは定数ポインタをインクリメントします。

+0

'argv'はポインタではなく、ポインタの配列です。ポインタは、ポインタを期待する関数に渡すときにのみ、ポインタへと減衰します。 –

+1

関連:http://stackoverflow.com/questions/6226027/incrementing-an-array-of-pointers-in-cここでは、事前標準のCプログラムを見ています。 –

+0

@AlexandreC .:いいえ、 'argv'はポインタの配列ではありません。関数パラメータ宣言の文脈では、 'T a []'は 'T * a'と解釈されることに注意してください。この場合、 'argv'は' char ** '型なので、' ++ 'は許されます。 –

答えて

2

まずとして定義される、argvのタイプは、(関数のパラメータ宣言の文脈において、T a[]T *aと同義であることを思い出してください)char **あります。したがって、配列型ではなくポインタ型であるため、++演算子の使用は直ちに許可されません。

第2に、旧式のK & R Cのように見えますが、それでも有効です。だから、表現argv++は完全に合法である

5.1.2.2.1 Program startup
...
2 If they are declared, the parameters to the main function shall obey the following constraints:
...
— The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

:ここではC99規格(n1256)が約argcargv言うことです。

4

argvはconstポインタではありません。これはchar *argv[]と定義されています。これはK&R Cあり、その定義はANSI Cで第二

よりも別の場所にあるので、それはconst char *argv[]と定義した場合でも、それは文字列定数から定期的なポインタです。そのポインタを使ってメモリに書き込むことはできませんが、ポインタ自体を変更することはできます。

文字列定数から定数ポインタは、すべてのconst char ** const argv

+0

したがって、K&R Cでは、これは有効です: int a [3]; a ++; – bhuwansahni

+0

これは私が知っているすべてのCリビジョンで有効です。しかし、関数のパラメータの型は他のところで定義されています。 – Gandaro

+0

これは有効なANSI Cではありません(gccから「エラー:増分オペランドとして必要な左辺値」を取得しています)、これは有効なK&Rのいずれでもないと思います。 'int * a; a ++'のようなポインタをインクリメントすることは有効です。ポインタは配列( 'int * a; a [2];')として使うことができますが、記憶空間で定義された配列はポインタと同じではありません。 –

関連する問題