● 重要な注意
前回および今回のプログラム例と解説は,初学者のために「平易」に解説を行っているため,必ずしも正 しくない説明や曖昧な説明になっている部分がある. 全て,次回以降に厳密に解説を行う予定である. 今回 までの授業内容を十分に理解し,より厳密な議論が理解できるようにする必要がある.
● 先週のプログラムのキーポイント
【変数】
「変数」とは「値を格納する名前が付いた場所」と(今のところは)理解しておけばよい. 変数は利 用する前に「定義」する必要がある.
プログラム内では,変数が定義できる場所は決まっていて,(当面の間)mainの「本体が始った直 後」にのみ定義できると理解しておこう.
#include <stdio.h>
int main(int argc, char **argv) {
/* ここに変数の定義を書く*/
/* その後にプログラムの実行文を書く*/
return 0 ; }
変数の定義の方法は(今回は)
int sum ; int i, j ;
などと書き, “int”の後に「変数の名前」を書いて定義する. ここで,i,j,sumなどが変数の名前で
あり, “int” とは,それらの変数が「整数型の変数」であることを示す. これらの変数は「整数型の
変数」であるため, 代入できる値は「整数」に限る. なお,「変数名」は大文字と小文字を区別する ので,iとIは異なる変数となる.
【変数の初期化】
Cでは, 全ての変数は「使う前に値を代入する必要がある」と理解するのが望ましい. 変数の定義と 同時に
int sum=0 ; int i=0, j ;
などと初期化することも可能である.
【変数への値の代入】
Cにおいてi = 0という「式」は,左辺にあらわれた変数(この場合はi)に,右辺の(式の)値(こ 0)を代入するという代入式である.
• 代入式は,右辺の式の値 を左辺の変数に代入する. したがって, i = i+1はiの値を 1だけ増 加させる.
• Cでは,i = i+1 を i += 1 と書くことができる. 一般に, 四則演算(加算 +,減算 -,乗算 *, 商 /,剰余%)などに対して i = i op jのかわりにi op= jと書くことができる.
【繰り返し】
プログラムを書く場合,ある条件の下で同じ内容の動作を何度か繰り返す必要がある. そのための「繰 り返し文」の一例が ex02-1.cなどにあらわれたforである.
★ for 文の構造
for(i=0;i<10;i+=1) { /* for の本体 */
}
forは括弧()内に;で区切られた3つの式を持つ.
• for文に出会うと「第1式」が実行される.
• 「第2式」が「真」である間,「forの本体」(繰り返し部分)を実行する.
• 繰り返し部分が1回終了するごとに「第3式」を実行し,その後に「第2式」を評価する.
したがって,上記のfor(i=0;i<10;i+=1)は
• 最初にi=0が実行される.
• i<10が評価され, それが「真」であるので,「繰り返し部分」が実行される.
• 「繰り返し部分」が終了すると iが 1増加し,再度i<10が評価される.
結果として, 10回の繰り返しが行われる.
★ while文の構造
Cでは, 別の繰り返し文としてwhile文があり,以下のような構造を持つ.
while(i<10) {
/* while の本体 */
}
whileは括弧 ()内にただ1つの式を持つ.
• while文に出会うと「式」が評価され,それが「真」である間,「whileの本体」(繰り返 し部分)を実行する.
• 繰り返し部分が1回終了すると「式」を評価する.
したがって,上記のwhile(i<10)はiが10未満の間「繰り返し」が行われる. forとは異な り,制御式に用いられた変数の「初期化」や「繰り返しごとの値の増分」などは,別個に記述す る必要がある.
【条件判断】
条件によって分岐する制御はif文を利用する.
if (i<10) { /* if 節 */
} または
if (i<10) { /* if 節 */
} else {
/* else 節 */
}
ifは括弧()内にただ1つの式を持つ.
• if文に出会うと「式」が評価され,それが「真」であるとき「if節」を実行する.
• 「else節」がある場合には,「式」が「偽」であるとき「else節」を実行する.
したがって, 上記の if (i<10) .. else は iが 10未満のとき「if節」が実行され, そう でないとき「else節」が実行される.
また,次のようにif ... else if ... elseと繰り返すことができる.
if (i<10) { /* if 節 */
}
else if (i<20) { /* else 節 */
} else {
/* else 節 */
} これは,
if (i<10) { /* if 節 */
} else {
if (i<20) { /* if 節 */
} else {
/* else 節 */
} }
の省略形であると思えばよい.
【比較演算子】
Cでの比較演算子には以下のものがある.
• ==等しい
• !=等しくない
• <,>より大きい,より小さい
• <=,>=以上,以下
この中で ==は=と間違いやすいので注意すること.
● 実習内容
【C言語】
1. 以下のex03-1.cを入力してコンパイルおよび実行を行ってみよう.
このプログラムは「1 から100までの整数の中で, 3または 5 で割りきれる数を出力する」も のである.
• 「または」は||であらわす.
• 「かつ」は&&であらわす.
2. 以下のex03-2.cを入力してコンパイルおよび実行を行ってみよう.
このプログラムは「100以下の素数を全て出力する」ものである.
• このプログラムは「素数を求めるプログラム」としては望ましいものではない!単に繰り 返し文と条件文の例として提示しただけである.
• どのような方法を用いているかは各自で考えること.
電子メールで「今日の講義の感想や意見」を送ってください.
★
ex03-1.c
の内容
/* 1 から 100 までの整数の中で, 3 または 5 で割りきれる数を出力する. */
/* $Id: ex03-1.c,v 1.5 2005-04-26 19:42:16+09 naito Exp $ */
/* ex03-1.c */
#include <stdio.h>
int main(int argc, char **argv) {
int n ;
for(n=1;n<=100;n+=1) {
if (((n%3) == 0)||((n%5) == 0)) { printf("%d\n", n) ;
} }
return 0 ; }
★
ex03-2.c
の内容
/* 100 以下の素数を全て出力する. */
/* $Id: ex03-2.c,v 1.2 2005-04-26 19:10:34+09 naito Exp $ */
/* ex03-2.c */
#include <stdio.h>
int main(int argc, char **argv) {
int i, n ;
printf("2\n") ;
for(n=3;n<=100;n+=2) { i = 3 ;
while(((n%i) != 0)&&(i<n)) { i += 2 ;
}
if (i == n) {
printf("%d\n", n) ; }
}
return 0 ; }
【課題】
★ exercise-03-1 西暦 1600 年から 2005 年までの間の閏年を全て出力するプログラムを書きな
さい.
● 前回の課題の解答例
★
exercise-02-3
n= 20として, k= 1, . . . , nに対して,それぞれのkを3 で割ったあまりを表示するプログラム.
/* $Id: exer-02-3-1.c,v 1.1 2005-04-26 19:14:27+09 naito Exp $ */
/* exercies-03-1.c */
#include <stdio.h>
int main(int argc, char **argv) {
int n ;
for(n=1;n<=20;n+=1) { if ((n%3) == 0) {
printf("%d: 3 で割った余りは 0\n", n) ; }
else if ((n%3) == 1) {
printf("%d: 3 で割った余りは 1\n", n) ; }
else {
printf("%d: 3 で割った余りは 2\n", n) ; }
}
return 0 ; }
最初はこの程度のプログラムでよいであろう.
ただし,このプログラムは n%3を2度計算しているという「ムダ」がある. このムダは,n%3の値を他の 変数に記憶させておけば解消できる. それを行ったのが次のプログラムである.
/* $Id: exer-02-3-2.c,v 1.1 2005-04-26 19:14:57+09 naito Exp $ */
/* exercies-03-1.c */
#include <stdio.h>
int main(int argc, char **argv) {
int n, m ;
for(n=1;n<=20;n+=1) { m = n%3 ;
if (m == 0) {
printf("%d: 3 で割った余りは 0\n", n) ; }
else if (m == 1) {
printf("%d: 3 で割った余りは 1\n", n) ; }
else {
printf("%d: 3 で割った余りは 2\n", n) ; }
}
return 0 ; }
すると,各if節,else節の中で同じ形のprintfが出てくることがわかるので,以下のように改良するこ とが可能である.
/* $Id: exer-02-3-3.c,v 1.3 2005-04-26 19:42:57+09 naito Exp $ */
/* exercies-03-1.c */
#include <stdio.h>
int main(int argc, char **argv) {
int n ;
for(n=1;n<=20;n+=1) {
printf("%d: 3 で割った余りは %d\n", n, n%3) ; }
return 0 ; }