情報処理概論目次

標準入出力だけを使った複写プログラム

テキスト(LaTeX)版はこちらです.

入出力だけを伴う手続き

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()
標準入力装置から入力された1文字を受け取る
putchar(文字)
1つの`文字'を標準出力装置へ出力する
すると,上の手続きは次のように表される.
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: }
このプログラムをここでは複写プログラムと呼んでおく. いくつかの注意をしておく.

ソースプログラムのコンパイル

ソースプログラムはC言語で書かれた単なるテキストファイルである. これをコンピュータ理解できる機械語(machine code)にまで変換しなければならない. このような作業をコンパイル(翻訳:compile)といい,そのためのソフトウェアをコンパイラ(翻訳系:compiler)と呼ぶ. コンパイラには次のような役割がある.

  1. ソースファイルを読み込んで,構文を解析して,プログラム言語の仕様に合致しているかをチェックする(文法違反があればエラーを知らせる).
  2. ソースファイルをコンパイルしてオブジェクプログラム(object program)を生成する.
  3. (いくつかの)オブジェクトプログラムをリンク(link)して,必要なライブラリ(library)や実行に必要なランタイムルーティン(runtime routine)を加えて,実行プログラム(executable program)を作成する.
C言語用のコンパイラには,GNUプロジェクトで開発されたgccがよく使われる.
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(シェル)が提供する入出力のリダイレクションのおかげである.


情報処理概論目次