argv - みる会図書館


検索対象: UNIX MAGAZINE 1991年2月号
6件見つかりました。

1. UNIX MAGAZINE 1991年2月号

IJN Ⅸ流プログラミング 4 す。つまり、現在の argv が指している内容 ( * argv 、つま り文字列 abc ) を示すのですが、この式の評価を終えた時 点では argv の内容には 1 が加えられて文字列 def を示す ように変史されます。初めてダブルポインタを使うときに はかなり混乱するかもしれませんが、いま自分が扱ってい るものがどんな型に属するのかをきちんと追っていけはさ ほど難しくはありません。どんどん使ってみましよう。 C 言語ではこのようにしてコマンド引数を処理しますが、 いったん使った引数をもう 1 度使いたいときにはかなり苦 労します。そこで、引数を再度使う可能性があるときには、 一時的な変数を用いてプログラムを書くこともあります。 次の例は、 1 次的な変数 ( i ) を用いて argc や argv の値を 変えすに同しプログラムを実現したものです。 % cat ーⅡ my—echo. c 1 main(argc , argv) 2 int argc ; * 矼空冂 ; 3 char 土 t 5 6 for (i 7 8 9 10 } 図ー C におけるコマンド行引数の処理 % my-echo abc def 00 ■ 00 住 a b c \ 0 d e f \ 0 住立■ 00 住 6 ・ a b c \ 0 d e f \ 0 1 ; i く argc puts ( 矼空 Ci] ) ; 3 0 \ 0 c h e a b c \ 0 d e f \ 0 このプログラムでは、 argv の 1 番目から (argc-l) 番目 までを出力しています。いくら C の配列が 0 から始まると いっても、 argv の場合には 0 番目はコマンド名が入ってい ますからそれを飛ばすことを忘れないように C 言語の記述力は柔軟ですから、ほかにもさまざまな書 int 型、 argv は char * * 型 ( 文字へのダブルポインタ ) で き方があると思います。ただし、基本的にはそれほど大き あることを宣言しています。 5 行目ではコマンド名を示し な違いはないはすです。慣れてきたら、これらに捕らわれ ている argv をスキップして、 6 行目以降で引数があるあ すに自分のスタイルで自由に書いてみましよう。 いだだけループしながらそれぞれの引数を出力しています。 ダブルポインタ argv の扱いにはちょっと注意が必要で 今回は、コマンド行として指定されたものを自分で書い す。 5 行目で、、 argv 十十〃としていますが、これは argv の たプログラムのなかでどのように活用するかについてお話 値を 1 つインクリメントするものです。この場合の、、 1 〃 ししました。指定されたものの文法的な解釈はひととおり とは argv の型、つまりポインタ型の 1 です。 argv に 1 を すませたつもりですが、意味的な解釈についてはまったく 加えると、 argv はその時点で指していたものの次を指すよ 触れていません。 UNIX には文法的な扱い方だけでなく、 うになります。図 1 ー 3 では、 argv は my-echo という文字 どんなコマンドでも同様に操作できるよう、特定の引数に 列を示すポインタを指していますが、 argv 十十という文の 対する取り決めがあります。次回は、このコマンド行オプ 実行によって abc という文字列を示すポインタを指すよ うに変わります。また、 7 行目では * argv 十十としていま ションについて説明する予定です。 ( いまいすみ・たかし東京工業大学 ) す。これは、優先順位の関係で * (argv 十十 ) と解釈されま UNIX MAGAZINE 1991.2 129

2. UNIX MAGAZINE 1991年2月号

IJN Ⅸ流プログラミング 4 echo $ 矼空 [$count] @ count = $count + 1 このプログラムでは、新たに count という変数を使って います。これは、何番目の引数を出力するのかを保持する ための変数です。この変数の値に従ってすべての引数を出 力するまでループを回りますが、ループの内部では引数の 出力と変数の値を更新しています。 @で始まっている行は、 C シェルの変数に対して数式の計算結果を代入するときに 使います。この例では、現在の count 変数の値に 1 を加え たものを新たに c 。 unt 変数に代入するという作業をして います。 foreach を用いた里 B シェルでは for を使えばすべての引数が簡単に指定 できましたが、 C シェルの場合はどうでしようか ? C シェ ルには、これに代わるものとして foreach という制御構 造か準備されています。これは、次のような形式で使用し end end コマンドの並び foreach 名前 ( 単語ー単語 2 . . 単語 n ) ます。 end echO $param foreach p 矼 ( $ * ) # ! /bin/csh ようになります。 foreach を使ってさきはどのプログラムを書くと、次の 128 は 2 つで、慣例的に名前は argc と argv となっています。 数を使ってコマンド行引数を処理します。通常、この引数 さて、最後は C 言語です。 C では、 main 関数に対する引 C におけるコマンド行引数 いほうがよいでしよう。 とはかぎりませんから、なるべくならばこの方法は採らな 簡単な引数ならこれでもよいのですが、かならすしもそう 合にも空白を含む引数があるときなどはうまく動きません。 ただし、 B シェルで $ * と $@が異なったように、この場 argc には、引数の数か格納されます。引数にはコマンド名 も含まれますから、コマンド名だけで引数を指定しなかっ たときにも argc は 1 となります。また、 argv には引数の 文字列それぞれへのポインタを格納する配列の基底アドレ スが格納されます。 ん ? 何を言っているのか分からない ? そうですね、も うすこし順序だてて説明しましよう。 C では文字列型は存在せす、文字の配列を利用して文字 列を表します。また、ポインタと配列はほば同しものとし て扱えます。 こまではよいでしようか ( 1990 年 11 月号 で文字列を使ったことを憶えていますか ? ) 。 C ではコマンド行引数は文字列として扱われますから、 B シェルや C シェルのように 1 つの変数に代入することは できません。そこで、この文字配列に引数が 1 っすっ代入 されます ( 図 1 ー 1 ) 。 これらの情報がはらばらに格納されていても、使いづら いだけです。そこで、 argv という配列変数にそれぞれの文 字列を示すポインタを格納します。このとき、最後の引数 を示す要素の次の要素として NULL が使われ、引数がそ こで終了していることを示します ( 図 1 ー 2 ) 。 さきほどの argv は文字列を小すポインタを要素とする 配列でしたが、配列とポインタは同しように扱えますから argv を文字列を示すポインタへのポインタ ( 文字へのダブ ルポインタ ) として扱うことも多いのです。 gv を文字へ のダブルホインタとみなすと、さきほどの図の argv に関 する部分は図 1 ー 3 のように変わります。 さて、コマンド行引数が関数に渡される仕組みさえ分か れは、あとはそれを使ってプログラムを書いてみるだけで す。次のプログラムは、ケえられた引数をすべて標準出力 に出力します。 % cat—n my—echo. c 1 main(argc , argv) 2 int 3 char 4 { 5 6 7 8 **argv ・ ; argv 十十 ; while (-—argc > の { puts ( * 矼空 + + ) ; argc ; 1 行目で main 関数を定義するときに引数として argc と argv をとることを宣言し、 2 行目と 3 行目で argc は UNIX MAGÄZINE 1991.2

3. UNIX MAGAZINE 1991年2月号

OSF, / Motif のすべて一② XtAppContext app-con ; Arg arg; Widget toplevel ; char **argv; int argc ; main(argc , argv) XtOverrideTrans1at i ons (toplevel , XtAppAddActions(app-con, quit-action, XtNumber(quit—action) ) ; if (argc ! = 1 ) s 坦 t ( 矼空 [ 0 ] ) ; (Cardina1 *)&argc, argv, L , NULL toplevel = XtAppInitia1ize(&app—con, "H0gege" , Ⅱ . L , Z 駅 0 Z 駅の ; XtParseTrans1ationTab1e("<Message>WM_PROTOCOLS : quit ( ) " ) ) ; XtCreateManagedWidget("hogege" , hogegeWidgetC1ass , toplevel , L , Z 駅の ; XtRea1izeWidget (toplevel) ; dpy = XtDisp1ay(top1eve1) ; wmDe1eteWindowAtom = XInternAtom(dpy, 'WM-DEIEIE-WINDOW" , Fa1se) ; (void) XSetWMProtoc01s(dpy, XtWindow(top1eve1) , &wmDe1eteWindowAtom, 1 ) ; XtAppMa1nLoop(app-con) ; [ リスト 2 : 設問一のもうーっの解答 ] wmPr0toc01sAtom = XInternAtom(dpy , "WM PROTOCOLS" , Fa1se) ; wmDe1eteWindowAtom = XInternAtom(dpy, "WM-DELffE-WINDOW" , Fa1se) ; XChangeProperty(dpy , XtWindow(top1eve1) , wmPr0toc01sAtom , XA-ATOM, 32 , PropModeRepIace , (unsigned char *)&wmDeleteWindowAtom, 1 ) ; MWM 固有のプロバティ OSF/Motif では、標準以外にも独自のプロバティを定 義し、ウインドウ管理に使用しています。それには、次の MOTIF WM_INFO _MOTIF_. _WM_PESSAGES MOTIF_WM_FEBIU MOTIF WM_HINTS ようなものがあります 74 ンや動作、あるいはウインドウメニューのアイテムを決定 これらによって、 mwm は各ウインドウのデコレーショ ができます。 すから、 XtSetValues などによって値をセットすること パティは VendorShell のリソースとして登録されていま ています。 MotifWidget を使用する場合、これらのプロ アトムは X コンソーシアムに届け出て登録することになっ ようけど ) を先頭につけます。このように、新しく定義した ( アンダースコア ) に続くべンダー名 ( 正確には OSF でし ICCCM の規約どおり、新しく追加するアトムには、、 したり、クライアントに対してメッセージを送ったりする 仕組みになっています。つまり、標準のプロバテイだけで は十分な制御ができないと判断したわけです。これについ ては賛否両論あることでしよう。 標準でない独自のプロバティを定義することによって、 それを考慮したクライアントに関してはウインドウの管理 ポリシーが明確になり、おそらくはユーサーにとって一貫 性のある使いやすい環境を提供することができるようにな るでしよう。 しかし、それは Motif ヌ、 fJ 芯のソフトウェアはかりで構成 される環境にのみいえることであり ( もちろん OSF の最 終目的はそのような環境なんでしようが ) 、現時点での X ウ インドウのフリーソフトウェアやアフリケーション資産な どを考えると、はたしてそういう環境が実現するかは疑問 の残るところですね。もっとも、実際のユーザーはそんな に気にしていないのかもしれません。 Motif 環境においては、、、 Motif 対応のソフトはより使 いやすく、そうでないものはそれなりに〃使いこなしてい くことになるのでしようか。 UNIX MAGAZINE 1991.2

4. UNIX MAGAZINE 1991年2月号

cc ¯pg ー 0 myprog filel. 0 fi1e2.0 オプジェクト・ファイルを作ったあとで、プログラムを 実行する。 . /silly gmon ・ out という名前のファイルを作る。結果を出力させ プログラムの実行が終了すると、現在ディレクトリに gprof silly るには、次のようにする。 UNIX MAGAZINE 1991.2 2.12 秒消費している。また、 fl は 10 , 000 回呼び出されて が分かる。 fl はそれ自身で 0.02 秒、その下の全ルーチンで 見ると、 2 番目に消費時間の多いルーチンは fl であること ンとその下の全ルーチンで消費される時間である。これを にの場合 98.6 パーセント ) があるが、これはこのルーチ ていて、クロス・リファレンスに役立つ。その後ろに % time いうエントリを見てほしい。この数はインデックスになっ が直接呼び出すルーチン全部だ。たとえば、 2 番目の [ 2 ] と すルーチン全部。逆に、それより下のものはそのルーチン 工ントリの上にリストされているのは、直接それを呼び出 リストは、各工ントリに 1 つのルーチンとなっている。 はとんどいつでも main ルーチンということになる。 から、リストの最初のルーチンが 100 パーセントに近く、 たものすべてで消費された時間の合計であるところだ。だ るのは、出力された時間がこのルーチンとそこから呼ばれ 力のように、時間消費の多い順に並んでいる。 prof と異な 第 3 の部分が gprof のメインディッシュだ。 prof の出 ろう。あまり興味ある数値とはいえない。 しなければ、プログラムは 1 マイクロ秒も走っていないだ main のなかのループで fl を 10 , 000 回も呼び出したり ので、総実行時間が数値の妥当性を左右する。たとえは、 は決まったレート ( 通常は毎秒 50 ~ 100 回 ) で集められる 間の統計をとるのに統計的アプローチを用いている。統計 正確なものか見当がつく。 prof と同しように、 gprof も時 分性の 1 行の要約。これを見れは、以下の数値がどの程度 いない ) 出力フォーマットの簡単な説明だ。第 2 の部分は細 の部分に分かれている。最初のところは ( 図 2 には示されて 図 2 は、得られた出力を縮めたものだ。出力はいくつか 連載 / 0 ADVISOR にする。 cc -c -pg filel . c cc -c —pg fi1e2. c 皿 = 0 ; main(argc , argv) 図ー int argc ; char * * argv ; int i ; for (i 0 ; i く 10000 ; f3() fl() f2() int int f or 1 ; sum 十 = i ; 0 ; i く 100 ; su.m ; 十十 ) 十十 ) cc -pg-osilly s Ⅲ Y. c でコンパイルされ、図 2 に示したフ 105 妙な点 など 70 ものルーチンになる。これらをはんとうに見たい gprof は audivC5] や --f-morefilesC20] や writevC70] える。 gprof にカウントが 0 の場合も含めるようにすれば、 やまったく呼び出されなかったルーチンに対する出力を抑 きに入った回数を数える ) mcount などの、、内部〃ルーチン づいたかな。私が削除したわけではない。 gprof は、 ( 手続 いくっかのインデックス・マークが抜けていることに気 関数名といったところだ。 の説明と prof スタイルのリスト、それにルーチンを示す 省略することにした。簡単にいえば、フィールドの 2 番目 編集者と友好関係を保ちたいので、残りの部分の説明は 味がある。一般にリストはこれよりもすっと長いし。 び出した。この簡潔な出力をていねいに調べていくのは意 f2 が ( 全部で 20 , 000 回呼び出されるうちの ) 10 , 000 回呼 いるが、すべて main からである。 fl は f3 を 10 , 000 回、 ロファイル・データを出す簡単なフログラム。

5. UNIX MAGAZINE 1991年2月号

が分かります。これらの機能を使ってすべての引数を出力 するプログラムを書くと、次のようになります。 % cat comline # ! /bin/csh while ( $ # 矼空 > 0 ) echo $ 1 shift end % comline a b c B シェルとほとんど同しですが、 C シェルでは while の 条件部に式が書けるので test コマンドを使わなくても記 述できます。 シェノレ変数 argv B シェルのあとで C シェルの説明に入ったので B シェル と同しような記述方法から始めましたが、実際に C シェル を使って書く場合には前述の変数 argv を利用するほうが 多いのです。位置パラメータは、 argv という変数の 1 番目 から順番に格納されています。このとき、 1 番目の引数を 指定するには、、 $argv[l]" と指定します。 % coml 土れ e a b echo $ 矼空 [ 3 ] echo $ 矼空 [ 2 ] echo $ 矼空 [ 1 ] # ! /bin/csh % cat comline UNIX MAGAZINE 1991.2 while ( $count く = $ # 矼空 ) set count=l # ! /bin/csh プログラムを作ると次のようになります。 これらを用いて、 C シェルらしくすべての引数を出力する ()* あるいは $argv[l-$#argv) としたときと同しです ) 。 し、すべての引数を指定するときは $ argv [ * ] となります ば、 2 ~ 4 番目の引数を指定する場合は $ argv [ 2 ー 4 ] です この方法を使えば、引数の範囲も指定できます。たとえ SC 翡 「 00t から / へのメッセージ 月 高野豊著定価し 600 円 か朝へのメッセー 日 人間とコンピュータを観察するスーパーユーサーの眼 日本に UN Ⅸが導入されたはかりの頃、突然管理を任された著者 の悪戦苦闘の経験をつづる。 UN Ⅸの権威者となった著者が、今ま でにめぐりあったさまざまなエピソードを紹介。夋に富む告白談と飽 くなき探求心の物語は多くのシステム管理者の共感を呼ふ、だろう。 たのしい LJN Ⅸ LJN ー X への招待 坂本文著定価し 900 円 好評を発売 UN Ⅸを「もっと」たのしく学べる入門書 「 UNIX MAGAZINE 」連載当初から大好評の「 UNIX への 招侍」の単行本イし UN Ⅸの根底にある文化や流儀をましえっ っ再構成、大幅加筆。ワークステーションの急速な普及によって UNIX 修得が急務と言われる現在、本書はまさに必読の 1 冊。 文書処理システム L±TEX 。 , ヵ 以リーランポート著、エドガー・クッ久倉沢良一監修、大野俊治、小倉博道、藤浦はる美訳、定価 2. 繝円 Le 引レ mpo を 使いやすさと豊富な機能えたマクロ・パッケージ い TEX は、最も進歩した組版システムといわ れる TEX を、使いやすくかっ実用性をさらに 咼めるためのマクロ・パッケージ。これを利 用すれば、複雑な数式すら、ユーザー自身 の手て、自在に文書レイアウトて、きる。開発者 自身が書いた決定版解説書。 Life with IJNIX LJ N ー X を愛するすべての人に ドン・ライプサ冫ケイ・レスラ共著坂本文監訳福夋博訳定価 3.000 円 ド、Ⅸを飛するすべて朝リ、に Lifcwith UNIX だれも知らなかった UN Ⅸの魅力の世界 UNIX の歴史的背景や、社会動向とともに、 UN Ⅸの技術面や市場面、今後の展望な どを幅広く解説。また UNIX 人名事典、アン グラ情報、名言などの貴重なデーターや一 風変わった情報を満載した。 UNIX ューザ ーに新しい視野を提供する好読物。 ・ UN Ⅸオペレーティングシステムは、 AT & T のベル研究所が開発し、 AT&T が ライセンスしています。※表示価格はすべて消費税込みです。 株式会社アスキー 〒 107-24 東京都港区南青山 6-11-1 スリーエフ南青山ヒル 株式会社アスキー書籍 / 雑誌営業部電話東京 ( 03 ) 86-1977 127

6. UNIX MAGAZINE 1991年2月号

IJN Ⅸ流プログラミング 4 どうです、美しくなったでしよう。シェルを用いて引数 をとるプログラムを書くときは、このように for を使うと 簡単にできます。 省略時の for の引数 さきほどは簡単に、、 $@の値が用いられる〃と書きました が、 B シェルにはすべての位置パラメータを指定する $ * と いう記法もあります。これらの違いはどこにあるのでしょ う力、 ? $ * ではすべての位置パラメータが並べられますが、 $@の場合にはそれぞれが二重引用符で囲まれたものにな ります。また、実際に使うときにはこれらの変数を二重引 用符で括った場合、括らなかった場合も含めて、全部で 4 通りについて考えなくてはなりません。そのあたりをテス トしてみましよう。 % cat comline # ! /bin/sh echo 'for param ) f or param do e ch0 $param done echo ' for param in $@) done echo $ p 矼 for param in " $@" echO ) for para.m 1 Ⅱ done echo $ p 矼 do for p 矼 in $@ 126 ます。 だ引数の場合ですから、 a "b c" という引数をなえてみ よく分かりません。相違が顕著に現われるのは空白を含ん しつは、このプログラムに通常の引数を与・えても違いは done e cho $param do for param in " $ * echO " $ * ) done echo $param for p 矼 in $ * echO ) for param. in $ * ) % comline a for p 矼 1 b c for p 矼 in $@ for param in " $@" for param in $ * for param " $ * " a b c 何も指定しないと、 $@ を指定したときと同様な結果が 得られます。このように、位置パラメータすべてを指定す るものでも、使い方によっては好ましくない結果となるこ ともありますから気をつけてください。通常は、上の例の ように $@ を使ったはうがよいでしよう 5 C シェルにおけるコマンド行引数 C シェルにおけるコマンド行引数の処理は、基本的には B シェルの場合と同様です。 % cat comline # ! /bin/csh echo $ 0 echo $ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 % comline a b c d e f g h i j k 1 comline a b c d e f g h i j k 1 B シェルと異なっているのは、 $ 数字としたときに 10 以 上の数字を使っても正確に引数が指定できる点です。また、 shift コマンドも利用できますし、すべての位置パラメータ を指定する $ * も使えます 6 。 引数の数を調べるには、 $#argv という記法を用います (argv については後述 ) 。 $ # 変数名という記法はその変数 UNIX MAGAZINE 1991.2 6 C シェルでは $@ は使えません。 解釈しているのかを考えてみるのもよいでしよう。 こではこれ以 E 説明しませんが、この出力を見てシェルがどのように引数を これを argv という変数に適用すれはコマンド行引数の数 にいくつの値が代入されているかを調べるものですから、 5