UNIXでは入出力の切り替え(リダイレクション)が記号『<』および『>』を使って利用者側で自由に行なうことが可能である.
標準入装置(キーボード)から入力される,または標準出力装置(モニタ)への出力するように設計されたソフトウェア(プログラム)であっても,UNIXが提供する入出力のリダイレクションを使うことによって,そのソフトウェアの利用範囲は飛躍的に拡大する.
ここでは,標準入力装置から1文字読み込んで,これを標準出力装置に出力するだけのプログラムを書く.
つまり,次のような操作を続ける.
この手続きは次のように書くことができる.標準入力装置から1文字受け取る; 標準出力装置へその文字を出力する; ....... ....... 標準入力装置から1文字受け取る; 標準出力装置へその文字を出力する; 以上を入力が終わりになるまで続ける
標準入力装置から1文字cを受け取る;
入力が終わりでない間,次を繰り返す;
標準出力装置へ文字cを出力する;
標準入力装置から1文字cを受け取る;
この手続きをwhile文を使って,次のように書き直すとわかりやすい.
標準入力装置から1文字cを受け取る
while (入力が終わりでない) {
標準出力装置へ文字cを出力する;
標準入力装置から1文字cを受け取る;
}
while文の一般形は,次のように条件式を使って
while (条件式) {
文1;
.... 文の並び;
文n;
}
と書く.
文と文の区切りをコロン『;』で表し,文1,....,文nという文の並びを中カッコ『{』と『}』で括って,論理的には1つの文としていることに注意する.
while文を書くときのように,文の並びが1つのブロックであることを明示するために字下げ(インデント)して書いていることに注意する. プログラムを書くときには,その論理構造がわかりやすいように,適切に字下げや改行を行なうことが極めて重要になる.これは,まず条件式を評価して,それがが真(true)であれば文の並びを実行し,もとに戻って再び条件式を評価する. 条件式がまた真であれば文の並びを繰り返し実行する........
したがって,while文は条件式が真である間は文の並びを条件式が偽(false)になるまで繰り返し実行する. 最初から条件式が偽のときには,while文にある文の並びは一度も実行されない.
while文の条件式が常に真であるときには文の並びが際限なく繰り返されることになる. これを無限ループという. 無限ループを持つプログラムはいつまでたっても終了しない. 手続きは有限時間内で終了する(処理を終える)ことが必要である.
いま,次の2つの手続きがあるとする.
getchar()
putchar(文字)
c = getchar();
while (c は入力の終わりでない) {
putchar(c);
c = getchar();
}
目的とする手続きをこのように書いたものをプログラム(program)と呼び,目的の処理を達成するプログラムを書くことをプログラミングという.コンピュータで実行可能なプログラムを書くために用いる特別な言葉をプログラム言語といい,今日まで多くの言語が開発されてきた. 代表的なプログラム言語には,Pascal(`パスカル'),C(`シー')やC++(`シープラスプラス'),LISP(`リスプ')やProlog(`プロローグ')などがある. 最近ではJava(`ジャバ')もある. Fortran(`フォートラン')などもあるが,最近ではあまり使われていない.
プログラミングの学習やコンピュータ技術やコンピュータ科学の世界では,CやC++などの言語が標準とされている. UNIXでは,AWKやPerlなどのスクリプト言語といわれるプログラム言語やシェルプログラムもさかんに使われており,極めて強力な情報処理が可能である.
演習:以下を実際に確かめてみよ.
Cでは,上のプログラムを以下のように書く.
これを,たとえば,ファイルcopy.cとしてエディタで作成せよ(Cプログラムのファイルの拡張子は常に.cでなければならない).
このようなファイルをソースプログラム(source program)といい,書かれたものをソースコード(source code)と呼ぶ.
説明の便宜のために左端に行数(1:から13:)を表示したが,実際のプログラムファイルには不要である.
1: /* 標準入力を標準出力に複写 */
2: #include <stdio.h>
3:
4: main()
5: {
6: int c;
7:
8: c = getchar();
9: while (c != EOF) {
10: putchar(c);
11: c = getchar();
12: }
13: }
このプログラムをここでは複写プログラムと呼んでおく.
いくつかの注意をしておく.
/*と*/で文字列を挟むと,その部分はプログラムとして無視される.
この書式はコメントとして利用される.
#include <stdio.h>は,プログラムの先頭に常に必要である.
オマジナイとして考えておく.
メイン文またはメイン関数と呼ばれ,その書式は『main(){』で始まり(4行目),『}』で閉じる(13行目)ように書く.
;』である.
cに代入する(格納する)という意味である.
cを整数型(integer)として宣言している.
(c != EOF)では,等しくない(not equal)ことを『!=』で表して,``変数cはEOFでない''を意味している.
EOFはファイルの終わり(End Of File)を表す.
ソースプログラムはC言語で書かれた単なるテキストファイルである. これをコンピュータ理解できる機械語(machine code)にまで変換しなければならない. このような作業をコンパイル(翻訳:compile)といい,そのためのソフトウェアをコンパイラ(翻訳系:compiler)と呼ぶ. コンパイラには次のような役割がある.
GNUプロジェクトはFSF(Free Software Foundation)が支援しているプログラム開発組織である. GNUプログラムで生み出されたソフトウェアを利用者は無料で利用することができる.最も基本的なgccの使い方は次のようにする. たとえば,次のソースプログラム
/* Hello, world を表示する */
#include <stdio.h>
main(){
printf("Hello, world\n");
}
をhello.cとして
とする. コンパイルに問題がなければ,このやり方では常に生成される実行ファイルは% gcc hello.c
a.outとなる.
これを実行すると次のようになる.
実行ファイル名を指定するにはコンパイラで% a.out Hello, world %
-o(小文字の`オー')オプションをつけて,次のようにする.
すると,実行ファイル名は% gcc -o hello hello.c
helloとなる.
先に作成した複写プログラムcopy.cを次のようにコンパイルする.
作成される実行プログラム% gcc -o copy copy.c
copyを使うと,標準入出力と標準出力,およびそのリダイレクションについて深い理解が得られる.
まず,プログラムcopyを実行させる.
何も起こらないが,キーボードから何文字かを入力してEnterキーを押す度に,入力した文字がエコーされることを観測する.
このプログラムを終了させるために,% copy sdkfifikdo sdkfifikdo pcve,edpf,epew,d pcve,edpf,epew,d ^d %
C-d(^d,つまりCntrlキーと同時にdを押す).
Enterキーが押されるまで,入力文字がエコーされないのは,入力文字が一旦バッファ(buffer)に貯められるからである.
いづれにせよ,標準入力装置から入力された文字が標準出力装置に出力されることには変わりない.
次に,入力をリダイレクトして何か適当なファイル,たとえばmyfileからcopyに入力してみる.
すると,標準入力に代わってファイル% copy < myfile
myfileからリダイレクトされた内容が標準出力装置に出力される.
つまり,ファイル内容がモニタに表示されることになる.
さらに,出力を適当なファイル,たとえばcopiedfileにリダイレクトする.
% copy < myfile > copiedfile % cat copiedfile
catでリダイレクト先のファイルcopiedfile内容を表示させて見ると,myfileと同じ内容であることがわかる.
つまり,実行ファイルcopyは与えられたファイルを別な名前でコピーすることができるのである.このファイルのコピープログラムでは,標準入出力の機能だけを使ってプログラムされていることを思い出せ. それだけの機能を使ってファイルのコピーが可能なのは,UNIXOS(シェル)が提供する入出力のリダイレクションのおかげである.