C 入門 - 総合情報センター

プログラミング言語
C 入門
東海大学総合情報センター
(第 4.2版)
目
第1章 C 言語とは
・・・・・・・・・・・
1.1 簡単な C プログラム
・・・・・・・・・・・
例題 1
・・・・・・・・・・・
1.2 プログラムの記述方法 ・・・・・・・・・・・
1.3 プログラムの説明
・・・・・・・・・・・
1.4 簡単な入出力
・・・・・・・・・・・
例題 2
・・・・・・・・・・・
演習問題 1
・・・・・・・・・・・
1.5 式
・・・・・・・・・・・
演習問題 2
・・・・・・・・・・・
演習問題 3
・・・・・・・・・・・
1
2
2
2
3
4
4
5
6
7
7
第2章 プログラミング
2.1
2.2
2.3
2.4
2.5
2.6
2.7
・・・・・・・・・・・ 8
パーソナルコンピュータの起動 ・・・ 8
ログイン
・・・・・・・・・・・ 8
ソースプログラムの作成(修正) ・・・ 9
コンパイルとリンク
・・・・・・・・・・・ 10
・・・・・・・・・・・ 11
実行
ログアウト
・・・・・・・・・・・ 11
パーソナルコンピュータの終了 ・・・ 11
第3章 条件分岐
3.1 if 文
例題 3
例題 4
演習問題4
3.2 switch-case 文
例題 5
演習問題 5
第4章 繰り返し
4.1 while 文
例題 6
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
12
12
12
13
13
14
14
15
・・・・・・・・・・・ 15
・・・・・・・・・・・ 15
・・・・・・・・・・・ 15
次
例題 7
演習問題 6
4.2 do-while 文
例題 8
4.3 for 文
例題 9
例題 10
演習問題 7
第5章 その他の文
5.1 break 文
例題 11
5.2 continue 文
例題 12
5.3 goto 文
例題 13
第6章 配列
6.1 一次元配列
例題 14
例題 15
演習問題 8
第7章 総合演習
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
15
16
16
17
17
18
18
19
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
20
20
20
21
21
22
22
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
23
23
24
24
25
・・・・・・・・・・・ 26
・・・・・・・・・・・ 26
演習問題 9(if 文)
演習問題 10
(switch-case 文、while 文) ・・・・・ 26
演習問題 11
(while 文、if 文)
・・・・・・・・・・・ 27
演習問題 12
(for 文、配列、if 文) ・・・・・・・・・・・ 28
付録
<注意> 本テキストでは\(エスケープ・シーケンス)の表記を、\ に統一します。
・・・・・・・・・・・ 29
第1章 C 言語とは
C 言語は 1973 年、米国 AT&T のベル研究所の Dennis M. Ritchie によって設計されたプログラミ
ング言語で、当初はオペレーティングシステム UNIX を開発するための言語として開発されました。
現在でもいくつかのオペレーティングシステムはアセンブリ言語によって作成されていますが、高級
言語である C 言語でオペレーティングシステムを記述することによって UNIX が他のプログラマにも
理解しやすいものとなり、各種のコンピュータに移植されるようになりました。オペレーティングシステ
ムの開発に使われることから、C 言語はアセンブリ言語と同等の機能を実現しており、システム記述
言語とも呼ばれています。また、現在ではオペレーティングシステムのみではなく、たくさんのアプリ
ケーションプログラムの開発に使用されています。特に UNIX では C 言語が標準でサポートされてお
り、UNIX 上で使われるほとんどのプログラムは C 言語で開発されています。
プログラミング言語には C 言語の他にも PASCAL、FORTRAN、COBOL など多数の高級言
語があります。それぞれのプログラミング言語には以下の特長があります。
FORTRAN
FORmula TRANslation の略です。文字どおり数式を容易にプロ
グラムに変換することを目的としたもので、主に科学技術計算などに
使用されます。
PASCAL
N.ヴィルトによって開発された言語で、教育用に適しています。
ブロック構造や再帰呼出しなどの機能があり、構造化プログラミング
に適しています。
COBOL
事務計算や多種大量の帳票作成や大量のデータを扱うのに適した
言語です。
PL/I
数値計算と事務計算のどちらでも効率よく開発できるように開発され
た言語ですが、コンパイラなどの処理系が大きくなっています。
BASIC
初心者向きのプログラミング言語です。インタプリタ上で開発すること
ができます。
Lisp
関数型の言語で、リスト処理に適しています。人工知能の分野でよく
使われています。
Prolog
Lisp と同様に人工知能の分野で使用されている言語で、「述語論
理」を記述することによってプログラムを記述します。
以上の言語と比較して、C 言語には次の特長があります。
1)C 言語の演算子としてコンピュータのハードウェアに近い機能を持っている。
(ビット演算子、シフト演算子、インクリメント/デクリメント演算子など)
2)プログラミングに必要な基本的な命令だけであり、命令の種類が少ない。
(式、複文、if 文、while 文、do-while 文、for 文、switch 文、break 文、
continue 文、goto 文、関数呼び出しなど)
3)豊富なデータ型を持つ。
(整数型、単精度浮動小数点型、倍精度浮動小数点型、文字型、ポインタ型、
配列、構造体、共用体など)
4)プログラムは関数の集りとして作成される。
1
1.1 簡単な C プログラム
ここでは簡単な C プログラムを解説しながら、C 言語とはどのようなものかを体験してみます。
例題1
2×3の計算(乗算)をするプログラムを以下に示します。
(プログラム例)
/*
example 1 */
#include <stdio.h>
void main()
{
int i, j, k;
i = 2;
j = 3;
k = i * j;
printf( "%d\n", k );
}
(出力例)
6
1.2 プログラムの記述方法
C プログラムを記述するときには、C 言語の文法に従う必要があります。プログラム(文)は任意の
場所から書き始め、文の終了は ;(セミコロン) によって示します。一行に複数の文を記述すること
もできます。また逆に、一つの文を複数行にわたって記述することもできます。このような記述方法を
フリーフォーマット(自由形式)といいます。ただし、できるだけ他の人が見たときに分りやすいように
記述しましょう。
(1)/*
example 1
*/
/* から */ で囲まれた文字列は注釈として取り扱われます。注釈は複数行にわたって記述する
こともできます。また、日本語で記述することもできます。
(2)#include <stdio.h>
#include <stdio.h> はヘッダファイル <stdio.h> をプログラム中に含めるこ
とをコンパイラに指示しています。<stdio.h> はシステム中に用意されているも
のであり、標準的に使用される記号、変数などが定義されています。
#include <stdio.h>
void main()
{
変数の宣言
・・・
プログラム
・・・
}
(3)プログラムの構造
C プログラムは右のように関数として定義し、関数の中に変数の宣言およびプログラムの記述を行
います。
2
1.3 プログラムの説明
(1) void main() (関数の宣言)
C 言語のプログラムでは、最低限 main という名前の関数の宣言が必要です。また、関数を宣言
する際には、関数の戻り値(その関数を実行したときに求まる値)の型(値の種類)を宣言します。この
例題では関数の戻り値の型として void が指定されています。これは戻り値として返す値がないこと
を示す特別な型の指定です。
(2) int
i , j , k ; (変数の宣言)
コンピュータ内では計算した値を一時的に記憶しておく入れ物が必要になりますが、この入れ物
のことを「変数」と呼びます。また、コンピュータ内では値として、小数点のついた値(123.5 など)と小
数点のつかない値(123 など)があり、それぞれ実数型、整数型と呼びます。変数も入れる値の種類
によって型を決める必要があります。
変数は名前によって区別されます。名前の命名には以下のような規則があります。
・英字で始まる英数字の文字列
・文字列の長さは 31 文字以内
・大文字と小文字は別のものとして認識される
プログラム中で使用する変数の型と名前は型宣言文で指定します。型宣言文 int で宣言された
変数は整数型変数と呼ばれ、12 などの整数の値をコンピュータ内で記憶するための入れ物として使
用されます。また、小数点の付く実数型(12.5 など)の値を記憶するための変数を宣言するには、以
下のように型宣言文 float を使用します。
float a, b, wa, sa;
プログラム中で必要となる変数は、あらかじめ宣言しておく必要があります。
(3) i = 2; (代入)
i = 2; は代入文と呼ばれ、=記号の右辺の計算結果を左辺の変数に代入します。この代入文に
よって変数 i の中に値 2 が代入されます。右辺で使用されている数値 2 は「定数」と呼ばれ、以下の
ような記述方法があります。
整数型定数
123
35
実数型定数
123.5
1235e-1 (1235×10-1)
続く行の
j = 3;
k = i * j;
も同様に、代入文です。それぞれの代入文が実行されると、変数 j には 3 が、変数 k には i と j の
積(C 言語では演算子*は乗算を表します)が代入されます。
右辺の式は「算術式」と呼ばれ、通常の計算式と同じように記述することができます。
a + b,
a - b,
a * b,
a - b * c, (a - b) * c
a / b, a % b
(演算子)
(演算子の優先順位)
3
(4) printf("%d¥n", k); (出力)
printf 文はコンピュータ内の値を人間が確認できるようにプリンタや画面に出力するために使いま
す。例題1のプログラムでは、計算結果の変数 k を表示します。どのように出力するかは、"%d¥n"の
ように文字列で指定します。%d は変数 k の値を10進数に変換して出力することを意味し、¥n は改
行の指示を意味します。出力方法を示す文字列の中で%や¥などの特殊文字のつかない文字はそ
のまま出力されます。たとえば、もう少し出力結果を工夫して以下のように値の前に文字を表示して
みます。
(出力例)
2 kakeru 3 wa 6
プログラムは以下のようになります。
printf("%d kakeru %d wa %d¥n", i, j, k);
この例題では文字列は printf 関数の中で使われましたが、これ以外の部分でもプログラムの中で
よく利用します。文字列を表すときには、「"」(ダブルクォーテースション)で囲んで表します。また、1
文字だけの文字を表す場合には、「’」(クォーテースション)で囲んで表します。
(5) (変数の初期化)
例題1では代入文を使って変数にあらかじめ値を与えてからその値を計算に利用しています。この
方法とは別にプログラムを実行する時点で、変数にある値を記憶させた状態で利用したい場合には、
変数を宣言するときにあらかじめ記憶させておきたい値を指定することができます。これを変数の初
期化と呼びます。例題1を変数の宣言の際に初期化を行うように書き換えて以下に示します。
/*
example 1 */
#include <stdio.h>
void main()
{
int i = 2, j = 3, k;
k = i * j;
printf( "%d\n", k );
}
1.4 簡単な入出力
例題1のプログラムでは、常に同じ値を計算するだけであり、他の値について計算することができ
ません。このような場合、値をデータとして入力することができます。計算結果を表示するために
printf 関数を用いましたが、データを入力するためには scanf 関数を用います。
例題2
乗算の計算をするプログラムを以下に示します。
(プログラム例)
4
/*
example 2
*/
#include <stdio.h>
void main()
{
int i, j, k;
scanf( "%d", &i );
scanf( "%d", &j );
k = i * j;
printf( "%d kakeru %d wa %d \n", i, j, k );
}
このプログラムをコンパイルした後、実行すると最初に入力を要求します。このとき、画面上に何も
表示されませんが、そのまま入力します。
(入力例)
2
3
(出力例)
2 kakeru 3 wa 6
それぞれの scanf 関数に対応した入力データが変数に読み込まれます。%d は整数の数値を読み
込む場合に使用します。また、scanf 関数では読み込んだ値を入れるための変数に&をつけます。
2はiに
3はjに
読み込まれます。その後は例題1と同じ計算が行われ、結果が出力されます。
演習問題 1
空欄を埋めて、a, b 2つの変数に実数を入力し、3a+2b を計算するプログラムを作成しなさい。
scanf( "%f", &a )における%f は入力するデータが実数形式であることを示しています。
説 明
プログラム
#include <stdio.h>
メインプログラムの開始
void main()
{
実数変数 a,b,c を宣言
a,b,c;
変数 a に値を読み込む
scanf( "%f", &a );
変数 b に値を読み込む
3a+2b を計算して c に代入する
変数 c の値を出力する
}
5
1.5 式
これまでは、簡単な例題を使った C 言語のプログラムスタイルを説明しました。ここでは、プログラ
ム中で使われる式についてもう少し詳しく説明します。
C 言語では他に次のような演算子があります。
(演算子)
加算
+
減算
−
除算
/
乗算
*
剰余
%
代入
=
インクリメント
++
デクリメント
−−
(1) 算術演算子
算術演算子の加算、減算、乗算については特に注意することはありませんが、除算については一
つだけ注意が必要です。整数型と整数型の除算の場合には小数点以下が切り捨てになり、結果は
整数型となることに注意してください。たとえば、6 / 3 の計算結果は 2 ですが、6 / 4 の計算結果は
1.5 ではなく 1 になります。また、6 / 12 の計算結果は 0.5 ではなく 0 となります。
剰余は、a % b とすることで、a を b で割った余りを求めます。たとえば、6 % 4 の計算結果はは 2
となります。
(2) インクリメント演算子、デクリメント演算子
インクリメント演算子は、変数の値に1を加えます。デクリメント演算子は、変数の値から1を引きま
す。この2つの演算子は、変数の前につけた場合(前置)と変数の後ろにつけた場合(後置)で結果
が異なります。例えば、変数 j の値が 10 であったとすると、
i = ++j ;
とすると、i は 11 、j も 11 になります。
i = j++ ;
とすると、i は 10 、j は 11 になります。
つまり後置の場合は、式を実行した後にインクリメントやデクリメントをおこなうのです。
(3) 代入演算子
代入演算子は、右辺の値を左辺の変数に入れる働きをします。
j = 10 ;
代入自体も一つの式ですので、値を持ちます。その値は代入された左辺の値となります。したがっ
て、
i = j = 10 ;
は、j に 10 を代入し、その結果(10 という値)を i に代入します。結果的に、i にも j にも 10 が代入さ
れます。代入演算子には、他にも以下のようなものがあります。
a += 10 ;
は、
a = a + 10 ;
と同じ意味になります。同様に減算、乗算、除算、剰余の各演算についても演算と同時に代入を行う
6
ための以下の代入演算子があります。
-=
*=
/=
%=
式は、これらの演算子や演算の優先順位を変えるためのカッコ ( ) を組み合わせて作ります。
(4) 型
式の中で整数型の値と実数型の値が混在している場合には、整数型の値を実数型の値(整数値
に .0 をつけた実数値)に変換して演算を行います。たとえば、「(1)算術演算子」の項目で 6 / 4 の
計算結果は整数型の 1 になることを説明しましたが、 6 / 4.0 は整数型定数と実数型定数の演算
ですので 6 が実数値 6.0 に変換されて実数型同士の演算が行われ計算結果は実数型の 1.5
になります。
変数についても使用する際に別の型として使用したい場合があります。たとえば変数 x が整数型
として宣言されている場合に x / 2 の値を実数型で求めるには、以下のように表記できます。
ひとつは x / 2.0 と表記する方法です。整数型の値と実数型の値が混在しているので整数型変
数 x の値を実数型の値に変換してから演算を行います。このとき変数 x に記憶している値が変化する
ことはありません。変数 x に記憶されている値を参照し、演算を行うための一時的な記憶場所で実数
型に変換してから演算に利用します。
もうひとつは (float)x / 2 と表記する方法です。変数(カッコでくくった式でもよい)の前に「 (型
名)」 をつけて変換する型を指定する方法です。(float)の指定により、変数 x の値が演算を行うため
の一時的な記憶場所で実数型に変換され、除算が行われます。このとき変数 x に記憶している値が
変化することはありません。
また、実数型変数の値を整数値として演算に利用したい場合には、(int)と変数の前に記述します。
実数値の小数部が切り捨てられて整数値に変換されます。たとえば、実数型変数 y に 45.67 の値が
記憶されているときに、(int)y の記述によって整数型の値 45 を演算に利用することができます。
演習問題 2
次の式を C 言語で記述しなさい。
(1) (a + b) ÷ (x - y)
(2) i を j で割った余りを k に代入する。
(3) a の値に1を加えて b に代入する。
演習問題 3
商品の単価と数量を入力し、金額を出力するプログラムを作成しなさい。
7
第2章 プログラミング
ここでは、実際にコンピュータを使ってプログラムを実行するまでの、実習の方法について説明し
ます。利用するコンピュータは、総合情報センターのアプリケーションサーバ(bosei)です。実習の流
れは次のようになります。
TeraTermPRO の起動
APサーバへログオン
ソースプログラムの作成(修正)
エラー
コンパイル・リンク
エラー
実行
ログアウト
2.1
パーソナルコンピュータの起動
パーソナルコンピュータの電源を入れ、Windows の初期画面を表示させます。なお、この手順に
ついての詳細は、端末室備え付けの『パーソナルコンピュータ操作ガイド』を参照して下さい。
2.2
ログイン
スタートボタンÆ「プログラム(P)」Æ「ネットワーク」Æ「TeraTerm PRO」をクリックする
と以下の画面が表示されます。「Tera Term New Connection」の Host:の欄から bosei を選択し
ok を押します。
8
UX/4800 (bosei) (pts/29)
login : 9jzz1234
←
Password:
各自のログイン名を入力します。
←
パスワードを入力しても何も表示されないので注意して下さ
い。
101 9jzz1234@bosei
←
これをプロンプトといいます。この状態でコマンドを入力す
ることができます。
2.3
ソースプログラムの作成(修正)
プログラムの作成または修正は ng エディタを使って行います。ここでは rensyu.c という名前の
プログラムを作成します。また、 c のプログラムの拡張子には「.c」を必ずつけるようにして下さい。そ
れでは例題のプログラムを入力してみましょう。
9jzz1234@bosei% ng rensyu.c
文字の修正は、次のようなキーを使って行います。
(BS キー)
カーソルの左側の文字を消去します。
(DEL キー)
カーソル上の文字を消去します。
(カーソル移動キー:↑、↓、← 、→ )
カーソルを上・下・左・右に移動します。
(TAB キー)
次の入力位置を右に8桁移動します。文の書き出しに6個の空白を入れる代わりに、
TAB キーを使うと便利です。
9
プログラム入力後、エディタを終了するためには CTRL キーを押しながら x、CTRL キーを押しな
がら c を押すると次のメッセージが画面下に表示されます。プログラムを保存するためには、yを入
力します。
Save file /uhome/a/9jzz1234/rensyu.c ? (y or n)
保存終了の場合はこのメッセージに対して y と答えます。
他にも ng エディタは以下のコマンドを使ってファイルを編集することができます。
カーソル位置から行末まで削除
CTRL - k
カーソルの前の文字を1文字削除
BS
カーソル上の文字を1文字削除
CTRL - d
CTRL - SPACE
CTRL - w
ESC
w
削除やコピーでバッファに保存された内容をカーソルの位置に挿入
CTRL - y
CTRL - x
※
※
カーソルの位置に始点を設定
CTRL - SPACE で設定した始点からカーソル位置までを削除してバッ
ファにコピー
CTRL - SPACE で設定された始点からカーソルの位置までをバッファ
にコピー
CTRL - c
ng エディタの終了
CTRL - k とは CTRL キーを押したまま k キーを押すことをいいます。
ESC
w
とは ESC キーを押した後、 w キーを押すことをいいます。
※ 他にも利用できるコマンドは数多くあります。詳細は湘南計算機室ホームページ
(http://www.cc.u-tokai.ac.jp/) から「オンラインマニュアル」の「ng エディタ」を参照してください。
2−4
コンパイルとリンク
実際にプログラムを動かすためには、コンパイル・リンクという作業をおこないます。コンパイルとは
プログラムをコンピュータが理解できる形式(機械語)に翻訳し、文法などに誤りがあるかを見つける
作業です。リンクとは入出力などのシステムに関連するプログラムをなどを集めて実行可能な形式に
する作業です。コンパイルとリンクは以下のコマンドで同時に実行できます。実行形式のファイル名を
指定しないと a.out という名前の実行形式のファイルができます。また、-o というオプションを使って実
行形式のファイル名を指定することもできます。
„
9jzz1234@bosei%
cc
rensyu.c
←実行形式 a.out を作成
„
9jzz1234@bosei%
cc
rensyu.c -o rensyu
←実行形式 rensyu を作成
作成したプログラム中に文法の誤りがあると、コンパイル時に error メッセージが表示されるので、
「2−3 プログラムの作成」からやり直し、誤りを訂正後ファイルを保存し、「2−4 コンパイ
ルとリンク」に進んでください。
10
2−5
実行
コンパイル・リンクによって作成された実行可能形式のファイルをコマンドとして入力します。
„
9jzz1234@bosei.cc% a.out
実行形式 a.out を実行
„
9jzz1234@bosei.cc% rensyu
実行形式 rensyu を実行
ここで、入力データが必要な場合は、プログラム中に記述されているフォーマットに従って、デ
ータを入力します。
2−6
ログアウト
セッションを終了します。bosei にログインをしたら最後には必ずログアウトが必要です。
9jzz234@bosei.cc%
logout
ログアウトを実行するとアプリケーションサーバとの接続が解除され「TeraTerm PRO」 のウイ
ンドウが閉じます。
2.7
パーソナルコンピュータの終了
実習を終了し、パーソナルコンピュータの電源を切る場合は、スタートボタン→「シャットダウ
ン(U)」をクリックします。「Windows のシャットダウン」というウインドウが開きますので、「コン
ピュータをシャットダウンする(S)」を選択して、「はい」をクリックします。しばらくすると、「コ
ンピュータの電源を切る準備ができました」と表示され自動的に電源が切れます。
この手順を行わずに、いきなり電源を切ることは絶対にしないで下さい。
注意
一部のコンピュータでは自動的に電源が切れません。「電源を切断しても安全です」と表示され
た後、電源スイッチを押して電源を切ってください。
11
第3章 条件分岐
3.1 if 文
if 文を使うと様々な条件による判定を行い、その条件を満たしているか満たしていないかによって
違う文を実行させることができます。
if(式){
偽
式
文1;
}
真
else{
文1
文2;
文2
}
上述のように「もし(if)」式の条件を満たしたときは、 文1 を「それ以外(else)」のときは 文2 を実
行する、という条件判定を行います。
また、文1、文2は一つの文だけではなく、複数の文を記述することができます。
例題 3
2つの数 a,b を読み込み、大小関係を判定して値の大きな方を出力するプログラムを作成しな
さい。
(プログラム例)
はじめ
#include <stdio.h>
void main()
{
int a, b;
scanf( "%d", &a );
scanf( "%d", &b );
if( a > b )
{
printf( "%d\n", a );
}
else
{
printf( "%d\n", b );
}
}
a,bを入力
いいえ
a>b
はい
a を出力
b を出力
おわり
プログラム中7行目の(a>b)を関係式といいます。
関係式の代表的なものを右の表に示します。
12
関係式
C 言語での表記
a = b
a == b
a ≠ b
a != b
a > b
a > b
a ≧ b
a >= b
a < b
a < b
a ≦ b
a <= b
例題 4
商品を7個ずつ箱詰めにする時、商品の数を入力すると必要な箱の数を計算し出力するプログラ
ムを作成しなさい。
(プログラム例)
#include <stdio.h>
はじ め
void main()
{
商品の 数を 入力
int m, n, hako ;
printf( "shohin no kazu ? " ) ;
そ れを 7 で 割っ た 余り
scanf( "%d", &n ) ;
余り が0
printf( "shohin no kazu = %d\n", n ) ;
いいえ
はい
m=n%7;
商が 箱の 数
商+1 が 箱の 数
if( m == 0 )
{
箱の 数を 出力
hako = n / 7;
おわり
}
else
{
hako = n / 7 + 1;
}
printf( "hako no kazu = %d\n", hako ) ;
}
また例題4の if 文のように実行する文が1つの場合は、次のように{ }を省略することも可能で
す。
if( m == 0 )
{
hako = n / 7;
{}省略可能
}
if( m == 0 )
hako = n / 7;
else
else
hako = n / 7 + 1;
{
演習問題 4
商品を箱詰めにする時、商品の数を入力し、必要な箱の数を出力するプログラムを作成
しなさい。6 個入りの箱を使った場合と、10 個入りの箱を使った場合の必要な箱の数を
出力するようにしなさい。
(出力)
shohin no kazu = 50
6 ko iri no baai = 9
10 ko iri no baai = 5
13
3.2 switch-case 文
switch-case 文を使うことにより、複数の条件の中からそれらの条件に合う場合と、どの条件にも
一致しない場合とに、処理を分けることができます。
switch( 式 ) {
case 定数1 : 文1; break;
case 定数2 : 文2; break;
.......
case 定数n : 文n; break;
default:
文m;
}
式
定数1
定数2
文1
文2
定数n
文n
その他
文m
式の値によって、その値が定数1と等しい場合には文1を実行し、定数2と等しい場合には文2を
実行し、定数nと等しい場合には文nを実行します。定数1から定数nまでのどれにも一致しない場合、
default:により文mを実行します。
また、文1、文2は一つの文だけではなく、複数の文を記述することができます。そして、break 文
を実行すると、switch 文を終了し、switch 文の次の文を実行することになります。
例題 5
1から12までの整数 a を読み込みそれぞれの月の名前を出力するプログラムを作成しなさい。
(プログラム例)
#include <stdio.h>
void main()
{
int a;
scanf( "%d", &a );
switch( a ) {
case 1 : printf( “January \n” ); break;
case 2 : printf( “February \n” ); break;
case 3 : printf( “March \n” ); break;
case 4 : printf( “April \n” ); break;
case 5 : printf( “May \n” ); break;
case 6 : printf( “June \n” ); break;
case 7 : printf( “July \n” ); break;
case 8 : printf( “August \n” ); break;
case 9 : printf( “September \n” ); break;
case 10 : printf( “October \n” ); break;
case 11 : printf( “November \n” ); break;
case 12 : printf( “December \n” ); break;
default : printf( “No match \n” );
はじめ
aを入力
a?
1
January
2
February
おわり
}
}
演習問題 5
整数を読み込み、1 から 3 までとそれ以外の場合とで、それぞれ、”menu1”,”menu2”,
“menu3”,”quit”を出力するプログラムを作成しなさい。
14
その他
No match
第4章 繰り返し
4.1 while 文
while 文を使うことにより、指定した条件を満たす間は文を繰り返し実行し、条件を満足しなくなっ
た場合には繰り返しを終了するといった制御を行うことができます。
while( 式 )
式
{
偽
真
文
文;
}
式で示される条件が満足されている間、文を実行し続けます。そして、条件が満足されなくなった
場合に while 文を終了し、次の文を実行するようになります。式の値によっては1回も繰り返しを行わ
ない場合もあります。なお、文は一つだけではなく、複数の文を記述することができます。
例題 6
はじめ
整数 a を繰り返し読み込み a の 2 乗を求めるプログラムを
作成しなさい。ただし、0 以下の値が入力されたらプログラムを
a を入力
終了するようにしなさい。
a>0
(プログラム例)
いいえ
はい
#include <stdio.h>
void main()
{
int a ;
scanf( "%d", &a );
while( a>0 )
{
a *= a;
printf( "The answer is = %d \n", a );
a =a*a
a を出力
a を入力
おわり
scanf( "%d", &a );
}
}
例題 7
整数 a を繰り返し読み込み a の 2 乗を求めるプログラムを作成しなさい。ただし、入力関数 scanf()
の戻り値(付録を参照)が EOF の場合にはプログラムを終了するようにしなさい。EOF は End Of
File を意味します。ファイルの終わりを示す特別な値を表しています。キーボードからデータを入力
している場合、データの終わり(入力ファイルの終わり)をプログラムに知らせるためには、CTRL キー
を押しながら D キーを押して、Enter キーを押します。
15
(プログラム例)
はじめ
#include <stdio.h>
void main()
{
int a ;
while( scanf( "%d", &a ) != EOF )
{
a *= a;
printf( "The answer is = %d \n", a );
}
}
a を入力
EOF
はい
いいえ
a =a*a
a を出力
a を入力
おわり
演習問題6
あるクラスで数学の試験を行った。その試験の点数をデータとして入力し、その合計点と平均点
を計算するプログラムを作成しなさい。なお、データの終了は EOF を判断するものとする。
(入力) 87
60
・・・
(出力)
Total = 675
Average = 67.5
4.2 do-while 文
do-while 文は while 文と同じように、指定した条件のもとでは文を繰り返し実行し、条件を満足し
なくなった場合には繰り返しを終了する制御を行うことができます。while 文との違いは、do-while 文
の場合には、繰り返し実行する文を先に実行してから、式で示された条件を満足しているかどうか調
べて次の繰り返しを行います。したがって、少なくとも1回は文が実行されることになります。なお、文
は一つだけではなく、複数の文を記述することができます。
do
{
文
文;
}
式
while( 式 );
真
16
偽
例題 8
はじめ
2 の n 乗の値を n の値を 1 から 1 ずつ増加させながら求める
n = 0, njyou = 1
プログラムを作成しなさい。ただし、2 の n 乗の値が 1000 以上の
値になったらその値を表示して終了します。
n=n+1
njyou = njyou *
(プログラム例)
#include <stdio.h>
void main()
{
int n = 0, njyou = 1;
do
{
n += 1;
njyou *= 2;
printf( "2
no
%d
n,njyou );
}
while( njyou < 1000 );
}
n, njyou を出力
njyou < 1000
いいえ
はい
jyou
wa
おわり
%d\n",
4.3 for文
for 文も while 文や do-while 文と同じく、条件が満足している間は文を繰り返し実行し、条件を満
足しなくなったら for 文を終了します。while 文や do-while 文よりも機能が多いので複雑な制御を行う
ことができます。
式1
for(式1;式2;式3)
式2
真
文
{
文;
}
偽
式3
for 文は最初に式1を計算し、次に式2の条件を判定します。条件を満足している場合に文を実行
し、さらに式3の計算を行ってから式2の条件判定の処理に戻ります。式2の条件を判定した結果、条
件を満足しなかった場合には、for 文を終了します。なお、文は一つだけではなく、複数の文を記述
することができます。
17
例題 9
整数 a をキーボードから読み込み 1 から a までの総和
(1+2+3+…+a)を求めるプログラムを for 文を使って作成しなさ
い。
はじめ
総和 c = 0
a を入力
b=0
(プログラム例)
#include <stdio.h>
void main()
{
int a, b, c;
c = 0;
scanf( "%d", &a );
for( b=1; b<=a; b++ )
{
c += b;
printf( “%d %d \n”, b, c );
}
}
いいえ
b は a 以下?
はい
c =c+ b
b, c を出力
b++
おわり
例題 10
1 から 50 までの整数の平方根の値を表にするプログラムを
はじめ
作成しなさい。
a=1
(プログラム例)
#include <stdio.h>
#include <math.h>
void main()
{
int a;
float y;
for ( a=1; a<=50; a++ )
{
y = sqrt( (float)a );
printf( "square root of %d = %f \n", a, y );
}
}
いいえ
a <= 50
はい
計算とその結果の出力
a=a+1
おわり
プログラム中で使われている sqrt()は平方根を計算するための関数であり、あらかじめ C 言語に
用意されているものです。
使い方は、最初に #include <math.h> を宣言し、その後平方根を求めたい式の中に sqrt()を記
述します。そのとき、()内には実数型の式を指定します。sqrt 関数は()内の値に対する平方根を求め
ます。この例では sqrt 関数の()内に(float)a と指定して整数型変数 a の値を実数型に変換して利用
しています。(7ページの「(4)型」を参照)
また、このプログラムをコンパイルする場合には、-lm オプションが必要になります。
18
演習問題 7
九九の計算をするプログラムを for 文を使用して作成しなさい。
(出力)
1
2
3
4
2
4
6
8
3
6
9
12
5
6
7
8
9
10 12
14
16
18
15
21
24
27
18
・・・・・・・・・・・・・・・・・・・・・・・
8
16
24
32
40
48
56
64
72
9
18
27
36
45
54
63
72
81
19
第5章 その他の文
5.1 break 文
break 文を使うことにより switch-case 文、while 文、do-while 文、for 文の途中で強制的にその文
を終了し、次の文を実行することができます。
break;
例題 11
はじめ
身長(cm)から 110 を引いた値を標準体重として、
実際の体重と標準体重の差を計算するプログラムを
身長と体重を入力
作成しなさい。ただし、入力データの終了でプログラ
ムが終了するようにしなさい。また、身長が 110 未満
の値の場合には間違ったデータが入力されたとみな
して、エラーメッセージを出力してプログラムを終了す
るようにしなさい。
EOF?
はい
いいえ
身長 < 110
いいえ
はい
エラーメッセージ
を出力
標準体重および
体重との差を計算
(プログラム例)
身長、体重、
#include <stdio.h>
標準体重および
void main()
その差を出力
{
int shincho, taiju, hyoujun, sa;
while(
scanf(
"%d
%d",
&shincho,
おわり
&taiju ) != EOF )
{
if( shincho < 110 )
{
printf( "ERROR DATA: shincho = %d taiju = %d\n", shincho, taiju );
break;
}
hyoujun = shincho – 110;
sa = taiju – hyoujun;
printf( "shincho = %d taiju = %d hyoujun = %d sa = %d\n",
shincho, taiju, hyoujun, sa );
}
}
20
5.2 continue 文
continue 文を使うことにより while 文、do-while 文、for 文の途中で強制的にそれ以降の繰り返し
の文を実行せずに次の繰り返しの条件判定を行わせることができます。なお、for 文の中で使われた
場合には、式3を実行してから次の繰り返しの条件判定を行うことになります。
はじめ
continue;
点数を入力
例題 12
ひとりの学生の英語、数学、国語の 3 科目の試験の点数
を入力してその学生の 3 科目の平均点を計算するプログラム
を作成しなさい。ただし、入力データの終了でプログラムが終
了するようにしなさい。また、試験を受けなかった科目につい
ては点数を -1 と入力することにして、一科目でも試験を受け
EOF?
はい
いいえ
点数 = -1
いいえ
はい
点数を出力
ていない科目がある場合には、その学生についての平均点
を求める処理は行わずに次の学生の処理へ移るようにしなさ
い。
平均点を計算
点数、平均点
を出力
(プログラム例)
#include <stdio.h>
void main()
{
おわり
int eigo, suugaku, kokugo;
float heikin;
while( scanf( "%d %d %d", &eigo, &suugaku, &kokugo ) != EOF )
{
if( eigo == -1 )
{
printf( "eigo = %d suugaku = %d kokugo = %d\n", eigo, suugaku, kokugo );
continue;
}
if( suugaku == -1 )
{
printf( "eigo = %d suugaku = %d kokugo = %d\n", eigo, suugaku, kokugo );
continue;
}
if( kokugo == -1 )
{
printf( "eigo = %d suugaku = %d kokugo = %d\n", eigo, suugaku, kokugo );
continue;
}
heikin = ( eigo + suugaku + kokugo ) / 3.0;
printf( "eigo = %d suugaku = %d kokugo = %d heikin = %f\n",
eigo, suugaku, kokugo, heikin );
}
}
21
5.3 goto 文
goto 文は指定した文へ実行を移す働きがあります。ただし、あまり使う必要のない文です。goto
文を多用することはプログラムの処理をわかりにくくすることにもなりかねないので注意して利用する
ようにしましょう。
goto 文は次のように記述します。
goto
ラベル;
・・・・・・
ラベル:
文;
ラベルは文の先頭に付けてその文の位置を示します。またラベルは名前で表されます。3ページ
の「変数の宣言」の部分で示したものと同じ規則の名前が利用できます。
例題 13
はじめ
あるクラスの数学の試験の点数をデータとし
て入力し、その平均点を計算するプログラムを
点数を入力
作成しなさい。ただし、入力データに負の値が
あった場合には、間違ったデータが入力され
EOF?
たとみなして、エラーメッセージを出力してプロ
はい
いいえ
グラムを終了するようにしなさい。
点数が負
はい
いいえ
人数を加算
合計を加算
(プログラム例)
#include <stdio.h>
void main()
{
平均点を計算
int suugaku, ninzuu = 0, gookei = 0;
エラーメッセージ
float heikin;
を出力
人数、平均点
while( scanf( "%d", &suugaku ) !=
を出力
EOF )
{
おわり
if( suugaku < 0 )
{
printf( "ERROR DATA: suugaku = %d\n", suugaku );
goto owari;
}
式の中の(float)ninzuu の部分は、
ninzuu += 1;
整数型変数 ninzuu の値を実数型
gookei += suugaku;
}
に変換してから計算に利用する
heikin = gookei / (float)ninzuu;
ように指示しています。(7ペー
printf( "ninzuu = %d heikin = %f\n", ninzuu, heikin );
ジの「(4)型」を参照)
owari: ;
}
22
第6章 配列
6.1 一次元配列
今までの例では使用する変数の個数がそれほど多くなかったので、それぞれの変数を宣言して
使用してきました。しかし、計算機では多くのデータを処理することがあります。
学生100人の試験点数を処理する場合について考えてみます。
今までの方法では以下のように100個の変数を宣言する必要があります。
int a001,a002,a003,a004,a005,a006,…,a098,a099,a100;
また合計を計算するにも、以下のようにたいへん長い文を記述する必要があります。
total=a001+a002+a003+a004+a005+a006+…+a098+a099+a100;
このような不便を解消するために考えられたのが配列です。配列を使うためには、データを格納
するのに必要な入れ物(配列要素)の個数を型と一緒に宣言します。
int a[100];
この例では、
型は int 型
配列名は a
配列要素の個数は 100
となります。また、配列を図で示すと以下のようになります。
配列 a
a[0]
a[1]
a[2]
a[3]
a[4]
a[5]
配列要素
a[99]
配列要素は配列名と[]の中に添字(配列要素を区別するための番号)を指定して表します。添字
には整数型の値(式または定数や変数)を指定します。添字は 0 から始まります。配列 a の配列要素
は a[0]から a[99]の100個になります。配列要素はひとつの変数として扱うことができます。たとえば
以下のような式が書けます。
total=a[0]+a[1]+a[2]+a[3]+a[4]+a[5]+…+a[98]+a[99];
変数の初期化と同じように、配列も宣言時に初期化をすることができます。たとえば、10個の配列要
素を持つ配列 b を初期値データとともに宣言するためには以下のようになります。
int b[10]={23, 56, 9, 38, 78, 55, 42, 76, 18, 30};
この宣言で b[0]から b[9]の10個の配列要素に初期値が設定されます。
文字型についても同じように配列を宣言したり、初期値を設定した配列を宣言することができます。
char chr[20];
char str[6]={ 'T', 'O', 'K', 'A', 'I','¥0' };
char univ[11]="University";
'¥0' は文字列の終わりを表します。また、 (ダブルクオーテーション)で文字列を囲った場
合にはコンパイル時に自動的に'¥0'が付加されます。
23
例題 14
あらかじめ整数型の配列に格納されているデータ中の最
はじめ
大値を見つけるプログラムを作成しなさい。なお、配列要素の
max
数は 10 とします。
=
k=1
(プログラム例)
#include <stdio.h>
k は 10 未満?
はい
void main()
{
int a[10]={23, 56, 9, 38, 78, 55, 42, 76, 18, 30};
int k, max;
max = a[0];
for( k=1; k<10; k++ ){
if( max < a[k] )max = a[k];
}
printf( "Max = %d\n", max );
}
いいえ
max は a[k]未満? いいえ
はい
max
=
k++
maxを表示
おわり
例題 15
あらかじめ配列に格納されている値の数だけ*記号を各行に印字するプログラムを作成しなさい。
ただし、配列要素の個数は10とする。
はじめ
(プログラム例)
k=0
#include <stdio.h>
k は 10 未満?
void main()
{
int a[10]={23, 56, 9, 38, 78, 55, 42, 76, 18, 30};
はい
m=1
int k, m;
m は a[k]以下?
for( k=0; k<10; k++ ){
for( m=1; m<=a[k]; m++ )putchar( '*' );
putchar( '\n' );
はい
*を1文字出力
m++
}
}
改行を出力
k++
おわり
24
いいえ
いいえ
演習問題 8
二つの配列 a, b にあらかじめ値が設定されている。配列 a と b のそれぞれの要素を加算し
て配列 c に格納し、その結果を印刷するプログラムを作成しなさい。ただし、配列 a と b は以
下のような値が設定されているものとする。
int a[10]={ 43, 76, 22, 28, 31, 45, 63, 70, 49, 51 };
int b[10]={ 12, 85, 46, 99, 36, 27, 19, 62, 44, 81 };
(出力)
a
b
c
43
12
55
76
85
161
22
46
68
28
99
127
・・・・・・・・・・・・
25
第7章 総合演習
演習問題 9(i f 文)
学生の試験の点数を入力し、その点数の値により、以下のようなメッセージを表示するプロ
グラムを作成しなさい。
80 点以上の場合
Yoku dekimasita
60 点以上 80 点未満の場合 Maa maa desune
60 点未満の場合
Jikai ha ganbarou
はじ め
点数を 入力
80 点以上?
いいえ
はい
いいえ
60 点以上?
Yoku dekimasita
はい
Jikai ha ganbarou
Maa maa desune
おわ り
演習問題 10(switch-case 文、while 文)
整 数 値 を 繰 り 返 し 読 み 込 み -1,0,1 お よ び そ れ 以 外 の 場 合 で 、 そ れ ぞ
れ”Error”,”False”,”True”を出力するプログラムを作成しなさい。なお、-2 が読み込まれたら、プ
ログラムを終了するように作成しなさい。
はじめ
aを入力
いいえ
a != -2
はい
a?
-1
0
False
Error
おわり
26
1 およびそれ以外
True
演習問題 11(while 文、if 文)
商品を 7 個ずつ箱詰めにする時、商品の数を入力し、箱の数を出力するプログラムを作
成しなさい。なお、商品の数が 0 だったらプログラムが終了するようにしなさい。
はじめ
商品の数を入力
商品の数が0
はい
いいえ
余りを計算
余りが 0
いいえ
はい
商が箱の数
商品の数と
箱の数を出力
おわり
27
商+1 が箱の数
演習問題 12(for 文、配列、if 文)
ある電車路線の運賃表が以下のようになっている。距離を入力したら、運賃を表示するプ
ログラムを作成しなさい。
3Km まで
140 円
30Km まで
480 円
6Km まで
180 円
35Km まで
570 円
10Km まで
190 円
40Km まで
650 円
15Km まで
230 円
45Km まで
740 円
20Km まで
320 円
50Km まで
820 円
25Km まで
400 円
なお、データは以下のようにあらかじめ配列に定義されているものとする。また、プログラムで
は for 文を途中で抜け出るようにしなければならないが、break 文によって解決できる。
int kyori[11] = { 3, 6, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
int unchin[11] = { 140, 180, 190, 230, 320, 400, 480, 570, 650, 740, 820 };
はじめ
距離(data)を入力
k=0
k は 11 未満?
いいえ
はい
data は kyori[k]以下?
はい
k++
data と unchin[k]を出力
おわり
28
いいえ
付 録
putchar(),getchar()関数について
標準出力に文字を出力します
putchar()
#include <stdio.h>
int putchar(int c );
戻り値:正常に出力できた場合には文字 c を、エラーの場合には EOF を返します。
標準入力から文字を入力します
getchar()
#include <stdio.h>
int getchar(void);
戻り値:正常に入力した場合には、読み込んだ文字を int 型に変換して返します。また、ファイル
エンド、エラーの場合には EOF を返します。パラメータとして(引数)void が指定されている場合には、
パラメータを何も指定する必要はありません。
標準入力、標準出力
標準入力、標準出力はプログラムが開始されるときにはオープンされています。したがって、プロ
グラム実行中は常に使用することができます。
標準出力ストリームからテキストを読み込み解釈します
scanf()
#include <stdio.h>
int scanf( const char *format [, address, ...] );
戻り値:正しくスキャンし、変換し、格納した入力フィールドの数を返します。ファイルエンドを読
み込んだ場合は、戻り値は EOF となります。値を格納したフィールドがなかった場合は、戻り値は0
となります。
一連の入力フィールドをスキャンして、1度に1文字ずつストリーム stdin から文字を読み込みま
す。次に、引き数 format によって指される書式文字列中の書式指定に従って、各フィールドを書
式化します。最後に、format の後に続く各引き数が示しているアドレスに、書式化した入力を格納し
ていきます。書式文字列中の書式指定の個数は、その後に続くアドレスの数と同じでなければなりま
せん。
書式指定:%[入力幅][型指定文字]
入力幅
読むべき文字数の最大値
型指定文字 次のとおりです
型指定文字
期待される入力
引き数の型
d
10進整数
int へのポインタ( int *arg )
x
16進整数
int へのポインタ( int *arg )
f
浮動小数点数
float へのポインタ( float *arg )
s
文字列
文字配列へのポインタ( char *arg[] )
c
文字
文字へのポインタ( char *arg )
29
フォーマットを指定してテキスト標準出力ストリームに出力します
printf()
#include <stdio.h>
int printf( const char *format [, argument, ... ] );
戻り値:出力したバイト数を返します。エラーの場合は EOF を返します。
format によって指される書式文字列中の書式指定を、format の後に続く各引き数に適用し、
書式化されたデータを stdout に出力します。書式指定は、後に続く引き数と同じ数だけなけれ
ばなりません。
書式指定:%[印字幅][.精度][型指定文字]
印字幅
印字する最小文字数
精度 印字する最大文字数
型指定文字 つぎのとおりです
型指定文字
入力引き数 出力の書式
d
整数
符号付き10進整数
x
整数
符号無し16進整数
f
浮動小数点
符号付きの dddd.dddd 形式の値
c
文字
1個の文字
s
文字列ポインタ
ヌル文字に出会うか、精度に達するまで
文字をプリントする
その他、テキスト中で使用された関数について
sqrt()
平方根を計算します
#include <math.h>
double sqrt(double x);
sqrt はパラメータで与えられる x の平方根を計算します。
30