ここでやっとプログラミングについて解説する。そのためには、プログラム言語を1つ定めてその文法を説明するとともに、プログラミングのノウハウについて解説していく。本講座では、最近特に注目されているC言語を用いることにする。
/* 1 */ /* Example program 3-1 */ /* 2 */ /* programmed by Nanashino Gonbe. 1992.4.1 */ /* 3 */ #include <stdio.h> /* 4 */ main() /* 5 */ { /* 6 */ printf(" This is a sample program for C language.\n"); /* 7 */ }プログラム3−1が一般的なCプログラムの基本スタイルである。以下、 1行づつ細かく解説する。
1,2: | 注釈文(コメント文)でCプログラムの実行には、一切影響しない文である。注釈は '/*' と '*/' の間に書かなければならない。通常プログラムの先頭や途中にこのように注釈行を入れ、プログラムに対する説明やプログラミングした人の名前,作成した日時などを記入しておく。こうすることによって、プログラムが読みやすくなったり、 Version 管理がしやすくなる。 |
3: | 標準入出力ライブラリを利用することを宣言する。ここでは、すべてのプログラムにこの宣言を入れると考えてよい。 |
4: | 関数名を書き、()内に引数を書く。引数については後で詳しく説明する。この場合関数名はmainである。Cプログラムにはmainが必要で、実行はmainから始まる。 |
5: | 関数mainの本体の範囲を示すための開始記号である。 |
6: | 実行結果を出力するための関数 printf を用いて、This is a sample program for C language.とメッセージを出力する。printf 関数で”と”で囲まれた部分の文字列を出力することができる。この文字列を変更することにより、異なったメッセージを出すことができる。文字列の最後の \n は、文字列出力後改行することを指示する制御文字である。但し,UNIXなどでは¥のかわりに\を用いるので注意されたい。(わきみち参照)実際 printf 関数本体も、main() と同様に{からプログラムが始まり}で終るスタイルをしている。 printf の関数の実体は標準入出力ライブラリ stdio.h の中にあり、頻繁に使われるような関数はここで用意されている。これを利用するために、3:のような宣言をする必要がある。 プログラムの1文の終には;(セミコロン)を付ける約束になっている。 |
7: | 関数mainの本体の範囲を示す終止記号である。 |
/* 1 */ /* Program 3-2 */ /* 2 */ /* 1991.4.2 */ /* 3 */ #include <stdio.h> /* 4 */ main() /* 5 */ { /* 6 */ int a, b, wa, sa, seki; /* 7 */ float syou; /* 8 */ /* 9 */ scanf("%d %d",&a,&b); /* 10 */ wa = a + b; /* 11 */ sa = a - b; /* 12 */ seki = a * b; /* 13 */ syou = a / b; /* 14 */ printf("%d %d %d %f\n",wa,sa,seki,syou); /* 15 */ }
1,2: | 注釈行である。1,2行に渡って注釈を書くことができる。しかしプログラム3−1のように、1行づつ /* */ で囲むことを勧める。 |
3: | 標準入出力関数ライブラリを利用することの宣言をする。実は、 #include は<>内に書かれたライブラリ(ファイル)を取り込むための命令であり、標準入出力関数ライブラリ名は stdio.h である。つまりこの位置に stdio.h の内容が挿入される。 |
6: | mainで用いる変数の宣言文である。int以下のa,b, ... , seki はそれぞれ整数を扱う変数であることを示している。これらの変数は、整数型(int型)であるという。 |
7: | 変数 syou を用いるための宣言である。変数syouは、浮動小数点型(float型)であることを宣言している。 |
8: | 6,7行目の宣言文と9行目以下の実行文との間に空白行を置き、プログラムを見やすくした。たいていの場合,宣言文と実行文あるいは実行文でも作業内容が異なるところで空白行を空けてプログラムを見やすくする。 |
9: | 標準入力関数 scanf を用い、変数aとbに数値を入力する。” ”内は入力フォーマットと呼び、%dは整数であることを示す。,後のaとbが入力する変数名であり、” ”内の1つ目の%dがaに、2つ目がbに対応している。変数名の前に&を付けているのは格納位置を示すためであり、scanf のパラメータとして格納位置を示してやる必要がある。ここでは、 scanf のパラメータには&を付けることと、&が付くことにより格納位置を示すことを覚えていればよい。 |
10: | 変数aの値と変数bの値を足した結果を変数waに代入する。この操作を代入と呼ぶ。数学の=は、左辺の値と右辺の値が等しいことを意味するが、Cプログラムでは、=は、=の右辺の値を左辺の変数に格納することを意味する。 よってCプログラムでは、
x = x + 1;のような代入文を書くことができる。これは、xの値に1を加えその結果をxに格納する文である。つまり、代入文の左辺は格納位置(メモリの番地)を、右辺は値を表している。 |
11: | 変数aの値と変数bの値を引いた結果を変数saに代入する。 |
12: | 変数aの値と変数bの値を掛けた結果を変数sekiに代入する。 |
13: | 変数aの値を変数bの値で割った結果を変数syouに代入する。一般的に、整数を整数で割った結果は実数になるため変数syouは、7:でfloat型で宣言した。14:標準出力関数 printf を用い10−13で計算した結果を出力する。printf の” ”を出力フォーマットと呼び、変数wa,sa,sekiの値が%dつまり整数で出力され、変数syouの値が%fつまり実数で出力される。 |
プログラムの文の終には;を付ける約束があったが、6−14の後ろには すべて;がついていることを確認すること。また、#include文,main() の 後ろには;を付けないことに注意せよ。
また、プログラムは上から下へと順に実行される。ここでは、9,10, 11,12,13,14と順に実行される。
/* 1 */ /* Program 3-3 */ /* 2 */ /* swap data 1992.4.3 */ /* 3 */ #include <stdio.h> /* 4 */ main() /* 5 */ { /* 6 */ int a, b, dummy; /* 7 */ /* 8 */ a = 10; /* initialize a <- 10 */ /* 9 */ b = 30; /* initialise b <- 30 */ /* 10 */ printf("initial state a = %d, b = %d\n",a,b); /* 11 */ /* 12 */ dummy = a; /* 13 */ a = b; /* 14 */ b = dummy; /* 15 */ printf("swapped state a = %d, b = %d\n",a,b); /* 16 */ }
8,9: | 初期状態として、変数aに10、変数bに30を代入する。 |
10: | printf関数を用いて,変数a,bの値を出力する。 |
12: | 変数dummyにaの値(つまり10)を代入する。この時点で変数aの値と変数dummyの値は共に10である。 |
13: | 変数aにbの値(30)を代入する。この時点で変数aとbの値は共に30である。 |
14: | 変数bにdummyの値(10)を代入する。この時点で変数bとdummyの値は共に10である。 |
15: | printf 関数を用いて、変数a、bの出力をする。 |
initial state a = 10, b = 30 swapped state a = 30, b = 10
ステップ aの値 bの値 dummyの値 ────────────────────────── 8 10 ? ? 9 10 30 ? 10 10 30 ? 11 10 30 ? 12 10 30 10 13 30 30 10 14 30 10 10 15 30 10 10
よって初期状態として aの値は10,bの値は30 であったが、ステ ップ15の出力時には、aが30,bが10に入れ換った。このように、2 つの変数の値を入れ換えるには、必ず一時的な変数(ここではdummy) を用意しステップ12,13,14のように3段階の操作を必要とする。こ れが変数の性質でもある。
a = b; b = a;とプログラムを変更したとき、結果がどうなるか。考察せよ。
/* 1 */ /* 文字型の利用 アスキーコードの出力 */ /* 2 */ /* 1992.4.29 */ /* 3 */ #include <stdio.h> /* 4 */ main() /* 5 */ { /* 6 */ char a, b, c, d, moji; /* 7 */ /* 8 */ a = 'A'; /* 9 */ b = 's'; /* 10 */ c = 'c'; /* 11 */ d = 'i'; /* 12 */ scanf("%c",&moji); /* 13 */ printf(" Input character: %c\n",moji); /* 14 */ printf(" %c%c%c%c%c code: %d\n", a, b, c, d, d, moji); /* 15 */ }
Z <------ moji に Z を入力した場合 Input character: Z <------ ステップ13の出力 Ascii code: 90 <------ ステップ14の出力
7 <------ moji に 7 を入力した場合 Input character: 7 <------ ステップ13の出力 Ascii code: 55 <------ ステップ14の出力
7: | 文字型の変数を利用する宣言である。 |
8: | 文字型の変数aに文字Aを代入する。=の右辺は文字定数であり、 ' と ' で囲まれた文字がその値である。ステップ8の実行後のaの値はAである。(通常 a の値は'A'であると記す) |
9−11: | ステップ8同様、文字の代入をしている。 |
12: | scanf 関数を用いて、文字の入力を行う。" "内の入力形式は %c と書くことにより文字型として入力することを意味する。ここでは、文字型変数 moji に文字の入力をする。ここでも moji の前に & を付けていることに注意せよ。 |
13: | printf 関数により、入力された文字の出力をする。出力フォーマットを %c とすることにより入力されたmojiの値を文字として出力できる。 |
14: | printf 関数により、代入した変数a,b,c,d,dの値を出力する。これらは、文字型の変数でありデータも文字型であるため、出力フォーマットとして %c を書く。また、最後の moji の出力フォーマットを %d とすることにより(アスキーコード)が出力される。第1章でも述べたように計算機の内部では、文字も数値(アスキーコード)として格納されているため、出力ファーマットの指定により文字を数値として出力することも可能である。 |
実行結果の二つ目の例で,mojiに’7’を入力した場合,Ascii code: 55 と出力されていたが,これは,入力された’7’は文字の’7’であって数 値の7ではないためである。数値の7として入力したい場合は,ステップ1 2の入力フォーマット制御記号(%c)を%dに変更すればよい。この場合 ステップ13のprintfでは
ここで、scanf と printf の入出力フォーマットと変数の型の関係について簡単にまとめておく。
型 | 表示形式 | 宣言 | 入出力フォーマットの制御記号 |
整数型 | 固定小数点表示 | int | %d(10進数として出力) |
実数型 | 浮動小数点表示 | float | %f(実数として出力) |
文字型 | 文字表示 | char | %c(文字として出力) |
整数型 | 固定小数点表示 | int | %x(16進数として出力) |
整数型 | 固定小数点表示 | int | %o(8進数として出力) |
わきみち
|