電子計算機及び実習 第 12回 (1/8) 12 Cプログラミング

12
C プログラミング
2008 年度 電子計算機及び実習
72
電子計算機及び実習 第 12 回 (1/8)
12
12.1
C プログラミング
今日のテーマ
* サンプルプログラム
* 簡単なプログラムの作成
** 今日の課題
課題 12.1,12.2 で作成されたファイル,test.txt, prog1.c を添付したメールを,s-suzuki 宛に署名をつけ
て送信せよ.
12.2
はじめに
今回は C 言語というプログラミング言語 によるプログラミングの基礎事項を概観するが,このレジュメだけ
では説明しきれない部分が多くある.詳しいことは文献をあたってほしい.C の参考書は数多く出版されており,
何を読んでも基本的には問題ないと思う.ここでは,C の原作者による以下の本をあげておく:
カーニハン& リッチー「プログラミング言語 C 第 2 版」
プログラミングは,計算機にやらせたいことを実行するプログラムを作成するための作業であり,主として,プ
ログラムの設計・ソースファイルの作成・コンパイル・実行・デバッグの5つの作業からなる.
第1段階 のプログラムの設計は,文字通り,どのようなプログラムを作りたいのか,どのような仕様にするの
かを考案する段階である.
第2段階 のソースファイル(プログラムリスト,プログラム,ソースなどともいう)の作成は,設計に基づい
て,計算機にやらせたい命令をエディター上でプログラミング言語を用いて記述しファイルに保存する段階であ
る.プログラミング言語は,その名の通り,プログラミングに使用する比較的人間に分かりやすい言語である.プ
ログラミング言語には,BASIC, Pascal, java, C++, Fortran などいくつもの種類があり今回使用する C 言語も
そのひとつである.
第3段階 のコンパイルとは,人間にわかる言葉で書かれたソースファイルを,計算機が実行できる形式に変換
する作業である.この変換に用いるコマンドをコンパイラーと呼ぶ.今回は C のコンパイラーとして gcc とい
うコマンドを用いる.コンパイルの段階で,ソースファイルがプログラミング言語の文法に従っていない場合な
どに,様々なエラーが出てコンパイルが完了しない場合がある.このようなエラーをコンパイルエラーとよぶ.
第4段階 の実行は,コンパイルして出来上がった実行形式のファイルを,実際に実行する段階である.実行し
た結果,無限ループに陥る,0 での割り算をするなど,様々な理由によるエラーや不具合が生じることもある.
第5段階 のデバッグとは,第3段階や第4段階で生じたエラーや不具合を修正する作業である.
コンパイルや実行の過程でエラーが出力されたり不具合が生じた場合は,その部分をエディター(Emacs)を
使って修正し,再びコンパイル・実行を行う.エディターを用いてソースファイルを作成し,コンパイラでコンパ
イルし,出来たコマンドを実行する,というのがプログラミングの基本的な流れである.これは,すでに TEX の
原稿を作成するときにも,同様の流れを体験しているので,それと比較して考えればわかりやすいであろう.な
お,通常,C プログラムのソースファイルには .c という拡張子を付ける. 今日の作業は,ホームディレクトリ下に,src というディレクトリを作って行うことにしよう.以下を実行し
なさい.
% cd
% mkdir src
% cd src
12
C プログラミング
12.3
2008 年度 電子計算機及び実習
73
サンプルプログラム
情報教育環境には,C の概要を学ぶためのサンプルプログラムが幾つか用意されている.まずは,それらをコ
ンパイルして実行してみよう.
「手引き」の Part III 第 9 章も参照しながら,以下の作業を行いなさい.
src ディレクトリの下で,以下のコマンドを実行しなさい53 .
% mksamp c
これによって,src ディレクトリに,7つのファイル (samp1.c, samp2.c, samp3.c, samp4.c, samp5.c, samp5.dat,
samp6.c) が作成されるはずである.
% ls
として,これを確認しなさい.
以下を順次実行しなさい.
コンパイル
% less samp1.c
% gcc -o samp1 samp1.c
% ./samp1
第1行目で,samp1.c の中身を確認し,第2行目で samp1.c をコンパイルして samp1 というコマンドを作成
し,第3行目でできたコマンドを実行している.gcc のオプション -o samp1 は samp1 という名前で実行形式の
ファイルを作れと言う意味である.
コンパイルエラーを体験しよう.以下を順次実行しなさい.
コンパイルエラー
% less samp2.c
% gcc -o samp2 samp2.c
コンパイルエラーが出力されるはずである.このようなエラーが出力された場合には,ソースファイルを修正
して,再びコンパイルしなくてはならない.
「手引き」を参考に,実際に Emacs で samp2.c を修正して,コンパ
イル・実行してみよ.
次に,実行時にエラーの出るプログラムの例を見てみよう.以下を順次実行しなさい.
実行時のエラー
% less samp3.c
% gcc -o samp3 samp3.c
% ./samp3
このプログラムは,標準入力(キーボード)から入力された整数で 10 を割った結果を標準出力(モニター)に
出力する.1, 2, −4, . . . など 0 以外の(比較的小さい)整数を入力している場合にはエラーは生じないが,0 を入
力するとエラーを生じることになる.実際に,標準入力から 0 を入力してみよ.
実行時にエラーが生じた場合にも,やはり,ソースファイルを変更して,エラーが生じないようにせねばなら
ない.
「手引き」では,samp3.c を samp4.c のように修正している.以下を順次実行しなさい.
ソースファイルの修正
% less samp4.c
% gcc -o samp4 samp4.c
% ./samp4
0 を入力してもエラーが生じないことを確かめなさい.
53 このコマンド
(% mksamp c) は教育環境で特別に用意されたコマンドであり, 他のシステムでは通用しない.
12
C プログラミング
2008 年度 電子計算機及び実習
74
上の samp3.c, samp4.c では,標準入力から数値を読みとって標準出力に数値を出しているが,ファイルから
入出力することもできる.その例が samp5.c, samp6.c である.以下を順次実行せよ.
% less samp5.c
% less samp5.dat
% gcc -o samp5 samp5.c
% ./samp5
% less samp6.c
% gcc -o samp6 samp6.c
% ./samp6
% less samp6.out
12.4
12.4.1
簡単な C プログラムの作成
最も簡単な C プログラム
以下の内容を,Emacs を用いて hello.c というファイルに書き込みなさい.
#include <stdio.h>
main(){
printf("Hello, world.\n");
}
このソースファイルをコンパイルして実行してみよう.以下を行いなさい.
% gcc -o hello hello.c
% ./hello
第 1 行目でコンパイル,第 2 行目でプログラムの実行を行っている.gcc がコンパイラの名前で,-o hello は,
hello という名前で実行形式のファイルを作れという意味である.
12.4.2
hello.c の説明
C のプログラムは複数の関数と呼ばれる小さな機能のまとまりを組み合わせることで書かれる.ソースの第 1
行目は stdio.h というファイルを読み込みなさいという意味で,この操作によって,C で標準で用意されている
関数群の一部 (printf もその一つである) が使えるようになる.C プログラムを書く際必要なオマジナイだと思っ
てもよい.
C プログラム中の関数の中で,main という関数は特別な関数である.main は,一つのプログラムを作る際に
必ず一つ,ソースファイル中に用意されなくてはならず,main 関数の中で,そのプログラムが実行する命令文が
順に書かれることになる.main の中に限らず 一つの命令文の終わりには必ずセミコロン ; を付ける.
printf は,ダブルクオートで挟まれた部分をモニターに出力する.また,\n は改行文字を表す.
12
C プログラミング
12.4.3
2008 年度 電子計算機及び実習
75
test.c
次に,以下の内容を,Emacs を用いて test.c というファイルに書き込みなさい.
#include <stdio.h>
/* ここ以下がメイン関数 */
int main(){
int i,j; /* i,j は int 型の変数である */
double x,y,z; /* x,y,z は double 型の変数である */
i = 36; j = 7; /* i,j に数値を代入 */
x = 1.0; y = -2.0; z = 2.343e7; /* x,y,z に数値を代入 */
printf("i=%d j=%d x=%f y=%f z=%f\n", i, j, x, y, z);
printf("i+j=%d i*j=%d i/j=%d j/i=%d i mod j=%d\n", i+j, i*j, i/j, j/i, i%j);
printf("x+y=%f x*y=%10.8f x/y=%g 1000*y-z=%g\n", x+y, x*y, x/y, 1000*y-z);
for(i=1;i<=10;i++){
x += 3.14;
}
printf("%f\n", x);
return(0); /* 正しく終了したという意味.これは作法 */
}
このソースファイルをコンパイルして実行してみよう.以下を行いなさい.
% gcc -o test test.c
% ./test
課題 12.1 test の出力結果を,test.txt というファイルに保存せよ (リダイレクト (>) を使えばよい).
12.4.4
test.c の説明
簡単に test.c の内容を説明しよう.
/* と */ で囲まれた部分はコメントとして扱われる.
C には何種類かの変数の型があり,char, int, float, double などがそれである.char, int は整数型,float, double
は実数型であり,データのサイズは,char が 1 バイト,int が 4 バイト,float が 4 バイト,double が 8 バイトと
なっている.cahr は 1 バイト文字を,int は整数を,float, double は実数を表す変数に用いられる.また,変数
の名前に用いることができる文字は,A–Z, a–z, 0–9, (アンダーライン) であり,変数名の長さに制限はない.int
main() の int というのは関数 main の返り値が int 型であるという意味である.また,
int i,j; /* i,j は int 型の変数である */
double x,y,z; /* x,y,z は double 型の変数である */
は,変数宣言とよばれる箇所であり,main 関数中で使われる変数を全て列挙し,その変数がどういう種類のもの
であるかを定義している.このプログラムでは,i, j は int 型,x, y, z は double 型であると宣言している.
i = 36; j = 7; /* i,j に数値を代入 */
x = 1.0; y = -2.0; z = 2.343e7; /* x,y,z に数値を代入 */
12
C プログラミング
2008 年度 電子計算機及び実習
76
= は代入を表す.i, j に整数を代入し,x, y, z に実数を代入している.実数の表現としては,2.343e7 (= 2.343×107 )
のようなものも使える.
printf("i=%d j=%d x=%f y=%f z=%f\n", i, j, x, y, z);
printf("i+j=%d i*j=%d i/j=%d j/i=%d i =%d (mod j) \n", i+j, i*j, i/j, j/i, i%j);
printf("x+y=%f x*y=%10.8f x/y=%g 1000*y-z=%g\n", x+y, x*y, x/y, 1000*y-z);
というのが,test.c の主内容である.標準出力54 に順に,i, j, x, y, z の値,i+j, ij, i/j の整数部, j/i の整
数部, i/j の余り,x+y, xy, x/y, 1000y-z を書き出せという意味である.printf は標準出力への書き出しを行
う関数であった.最初の引数で,標準出力に出力する 2 番目以降の引数の型と出力フォーマットを指定する.%d
は int, %f, %g は float もしくは double であり,例えば,%10.8f は実数を小数点以下 8 桁の全 10 桁で表示せよ
という意味になる.
for(i=1;i<=10;i++){
x += 3.14;
}
printf("%f\n", x);
の部分は,i が 1 から 10 になるまで,x+ = 3.14 を実行し,その結果を出力せよという意味である.ただし,
x+ = 3.14 とは, 変数 x に 値 x + 3.14 を代入する, という意味である.
k
∑
1
課題 12.2 キーボードから整数値 k を入力したら,
の値を標準出力またはファイルに出力するプログラム
n2
n=1
prog1.c を作りコンパイルして,実行せよ.また,k = 10 の場合の結果をメモしなさい.
ヒント. C を初めて扱う者は, なかなか思い通りに動くプログラムは作れないだろう. 本節の説明を良く読み, こ
れまでのサンプルプログラムの挙動を良く理解すれば, 上記のプログラムは作れるはずである.
12.5
本日の課題
課題 12.1,12.2 で作成されたファイル,test.txt, prog1.c を添付したメールを,s-suzuki 宛に署名をつけ
て送信せよ.ただし,Subject は 「学籍番号+Jan08」とせよ.また,メールの本文に,課題 12.2 でメモした値
および添付したファイルの名前を明記しなさい.
54 UNIX には標準入力 (stdin,通常キーボード),標準出力 (stdout,通常ディスプレー),標準エラー出力 (stderr,通常ディスプレー) と
いう 3 種類の入出力が用意されている.