システム・プログラム 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/syspro-2004/2004-04-19
/argv.html
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~yas/
http://www.is.tsukuba.ac.jp/~yas/index-j.html
1: /* 2: arg-print.c -- mainの引数を表示するプログラム 3: ~yas/syspro/proc/arg-print.c 4: Start: 1997/04/21 18:23:13 5: */ 6: 7: main( int argc, char *argv[], char *envp[] ) 8: { 9: int i ; 10: printf("&argc == 0x%x, argc == %d\n", &argc, argc ); 11: printf("&argv == 0x%x, argv == 0x%x\n",&argv, argv ); 12: for( i=0 ; argv[i] ; i++ ) 13: printf("argv[%d]==0x%x, \"%s\"\n",i,argv[i],argv[i] ); 14: }実行例。
% cp ~yas/syspro/proc/arg-print.c .argv[0] には、プログラムの名前が含まれている。argv[1] 以降に、普通の意 味での引数が含まれている。argc には、プログラムの名前まで含めての引数 の数が含まれている。argv[0] からargv[argc-1] まで参照できる。 argv[argc] は、参照してはいけない(0が入っているはずではあるが)。% make arg-print
cc arg-print.c -o arg-print % ./arg-print
&argc == 0xbfffe7c0, argc == 1 &argv == 0xbfffe7c4, argv == 0xbfffe824 argv[0]==0xbffffa81, "./arg-print" % ./arg-print who am i
&argc == 0xbfffe740, argc == 4 &argv == 0xbfffe744, argv == 0xbfffe7a4 argv[0]==0xbffffa78, "./arg-print" argv[1]==0xbffffa84, "who" argv[2]==0xbffffa88, "am" argv[3]==0xbffffa8b, "i" %
![]()
argvは、2次元配列ではない。
char へのポインタの配列の先頭番地を入れた変数である。
図? argvの構造
char *argv[]
は、*argv[0] と書いたら char 型(8ビットの
整数)という意味である。
C言語で char *p
と宣言した時、*p
と p[0]
は、
同じ意味になる。
*(p+1)
と p[1]
も同じ意味になる。
2次元配列は、C言語では配列の配列として表される。
char array[10][20];これで、全部で 10*20*1 == 200 バイトのメモリが確保される。array[i][j] の番地を計算するには、次のようになる。
(1) arrayの先頭番地を求める。 (2) (1)の値に + i*20 を加える。 (3) (2)の値に j を加える。array[10][20] のうち、最初の [10] は、番地の計算には使われない。
main() の引数で char *argv[] と char **argv は、同じ意味になる。 argv[i] は、 *(argv+i)、 argv[i][j] は、*(*(argv+i)+j) という意味になる。
char *argv[] で、argv[i][j] と書いた時の番地の計算の仕方は、次のように なる。
(1) argv の番地の内容を load する。 (2) (1)の値に + i*4 を加え、その値の番地の内容を load する。 (3) (2)の値に j を加える。2次元配列と違って、番地を求めるだけで、間に load が2回入る所に注意す る。2次元配列だと番地を計算する時には、load は出てこない。
(main の)引数で、char *argv[] と char **argv は、よいが、char argv[][] は、伝統的にはエラーになる。argv[i][j] を計算しようとすると、i を何倍 してよいのか計算できないので。しかし、受け付けるコンパイラもある。
C 言語で、char a[10] とした時には、10 バイトの領域が確保される。しかし、 char *p 宣言しただけでは、ポインタ自身(4バイト)の領域は確保されるが、 その先の領域は確保されない。
ポインタは、必ず番地をセットしてから使う。次のプログラムは、誤りである。
main() { char *p ; *p = 'A' ; }