システム・プログラム
電子・情報工学系
新城 靖
<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' ;
}