2. if文を用いたプログラムの流れの分岐
INDEX

目標

  • 条件によって2つの処理の中からいずれか一つを選択するプログラムをif〜else〜文を使って実現することができる。
  • 関係演算子や等価演算子を使って条件式を作ることができる。
  • 二つ以上の条件をif〜else〜文を使って判定し処理することができる。
  • 複数の条件を論理演算子を使って一つにまとめることができる。

予習・復習

 以下のスライドを利用して、予習と復習をしよう。復習では、自分の理解度を確認するために、実際にプログラムを作成し、意図する結果が得られるか確認しよう。
  1. if文
  2. 論理演算

本日の講義・演習予定

  1. もし〜ならば・・・ if文
  2. もし〜ならば・・・そうでなければ... if 〜 else 〜文
  3. いろいろなif文
  4. 演習問題1
  5. 論理演算、ORとANDとNOT
  6. 演習問題2
  7. 提出課題
内 容
  1. もし〜ならば・・・ if文
  2. もし〜ならば・・・そうでなければ... if 〜 else 〜文
  3. いろいろなif文

もし〜ならば・・・if文

真と偽

 プログラムでは「状態」を判定するために、条件(式)をつくる必要があります。例えば、整数型の変数aの値が0より大きいかを判定するための条件式は
a > 0
と記述することができます。記号 >(より大きい) は大小関係を判定する比較演算子の一つです。変数aの値が5ならばこの条件式は成立したことになります。変数aの値が0ならば成立しません。この条件が成立した状態を真(true)と言い、条件が成立しなかった状態を偽(false)と言います。

条件が成立した場合にだけ処理をする

 整数を入力して絶対値を求めるプログラムを考えてみましょう。絶対値はその値が正ならばその値自身となり、負ならば符号を取り除いた値になります。すなわち、「値が0より小さい」という条件が成立した場合にのみ「符号を反転する」という処理を行えば良いわけです。このような場合の処理はif文を使うことで実現することができます。以下にプログラム例を示します。
例 if.c
#include <stdio.h>

int main(void)
{
	int a;
	
	printf("整数>> ");
	scanf("%d", &a);

	if (a < 0) {		// 0より小さい、すなわち負の整数ならば
		a = -1*a;		// 符号を反転
	}
	printf("絶対値 %d¥n", a);
	
	return 0;
}
構文:
if ( 条件 ) {
    条件が「真」の時に処理される;
}
 キーワードifの後のカッコの中に「条件(式)」を記述します。「変数aが0より小さければ」という条件式は「a<0」と表記できます。条件の評価結果が真ならば直後の波カッコ{ }内の文を処理します。偽ならば波カッコ{ }内の処理は飛ばしてその後の処理に進みます。  if文をフローチャートを使って表わすと下図のようになります。
if
条件が成立すれば「真(true)」、そうでなければ「偽(false)」と評価される

条件式に使える演算子

関係演算子

演算子説明記述例説明
>大きいa>100aは100より大きい
>=大きいか等しいa>=100aは100以上
<小さいa<100aは100より小さい
<=小さいか等しいa<=100aは100以下

等価演算子

演算子説明記述例説明
==等しいa==100aが100なら
!=等しくないa!=100aが100でないなら

もし〜ならば・・・そうでなければ・・・ if 〜 else〜文

if〜else文

 「お買い上げ金額が5000円以上ならば500円引、そうでなければ100円引」のように、条件が真(true)の時と偽(false)の時とでは異なる処理をしたいことがあります。このような二者択一を実現するための構文には、if(条件){・・・}else{...} があります。
例 ifelse.c
#include <stdio.h>

int main(void)
{
	int price;
	
	printf("お買い上げ金額>> ");
	scanf("%d", &price);

	if (price >= 5000) {		//5000円以上ならば
		price = price - 500;		//500円引き
	}
	else {
		price = price - 100;		//100円引き
	}
	
	printf("お支払い金額 %d\n", price);
	
	return 0;
}
構文:
if ( 条件 ) {
    条件が「真」の時に処理される
}
else
{
    条件が「偽」の時に処理される
}
 if〜else文をフローチャートを使うと下図のように表わすことができます。条件が「真」ならば文1を処理し、「偽」ならば文2を処理します。 if

真偽の値

 C言語には真(true)か偽(false)を表すための特別な型はなく、偽を整数の0で、真を整数の0以外の値を使って表しています。
 次の例では2つの整数を入力して、その大小関係の真偽を表示します。実行して、その評価結果が偽ならば0で、真ならば1で表示されることを確認してみましょう。
例 truefalse.c
#include <stdio.h>

int main(void)
{
	int a,b;
     
    printf("整数(a,b)>> ");
    scanf("%d,%d", &a,&b);
 
    printf("a==b -> %d\n", a==b);
    printf("a>b  -> %d\n", a>b);
    printf("a<b  -> %d\n", a<b);

	return 0;
}
「真(true)」整数の0以外の値で、「偽(false)」は整数の1で表わされる

NOTE: c99以降では標準ライブラリに論理型と論理値を扱うためのライブラリが追加されました。ヘッダstdbool.hをインクルードすることで論理型boolが、真偽を表す論理値trueとfalseが利用できるようになります。trueは整数の1にfalseは整数の0として定義されています。

いろいろなif文

偶数と奇数

 整数を入力して、「偶数」か「奇数」かを判定するプログラムを考えましょう。任意の整数は必ず「奇数」か「偶数」のいずれかの集合に含まれます。ですから、二者択一の構文を実現するif〜else文が使えることが分かります。また、その判定条件は、2で割った余りが0か1かで判定できます。以下に剰余演算子を使ったプログラム例を示します。
例 oddeven.c
#include <stdio.h>

int main(void)
{
	int a;
     
    printf("整数>> ");
    scanf("%d", &a);
 
    if (a%2==0) {				//2で割り切れれば偶数
        printf("偶数です。\n");
    }
    else {
        printf("奇数です。\n");
    }
	
	return 0;
}

次も、真偽の判定は逆なりますが、同じ偶数奇数を判定するプログラムです。真と偽が整数の0と1で判定されていることから空欄アにはどんな式を入れたら良いでしょう。
例 oddeven2.c
#include <stdio.h>

int main(void)
{
	int a;
     
    printf("整数>> ");
    scanf("%d", &a);
 
    if ([[空欄ア]]) {			//余りが1なら奇数
        printf("奇数です。\n");
    }
    else {
        printf("偶数です。\n");
    }
	
	return 0;
}

2つの独立した条件

 整数を入力して、2の倍数ならば「2の倍数です。」、3の倍数ならば「3の倍数です。」と表示するプログラムを考えます。例えば、8が入力されれば「2の倍数」、9が入力されれば「3の倍数」になります。6ならば両方のメッセージが出力されることになります。これは、二つの事象が独立して起こりうることを示しています。このよう場合は、二者択一のif else文ではなく、それぞれの条件を別々に判定するために2つのif文を使って構成する必要があります。
multiples.c
#include <stdio.h>

int main(void)
{
	int a;
     
    printf("整数>> ");
    scanf("%d", &a);
 
    if (a%2==0) {
        printf("2の倍数です。\n");
    }
    if (a%3==0) {
        printf("3の倍数です。\n");
    }
	
	return 0;
}

三者択一

 入力した整数が、「正」か「負」か「0」かを判定するプログラムを考えましょう。変数名をnとするとそれぞれの条件式は、「n>0」、「n<0」、「n==0」となります。三者択一の構文は二者択一のif〜else文を組み合わて枝分かれを2段にすることで三者択一を実現します。下図のフローチャートを見てください。まずひとつ目の判定条件「n>0」で二つに枝分かれします。判定が真ならば「正」です。偽ならばもう一つの判定条件「n<0」でさらに二つに枝分かれします。判定が真ならば「負」なり、偽ならば残りの条件である「0」と判定できます。
if else if else
select3.c
#include <stdio.h>

int main(void)
{
	int n;
     
    printf("整数>> ");
    scanf("%d", &n);
 
    if (n>0) {
        printf("正です。\n");
    }
    else if(n<0){
        printf("負です。\n");
    }
    else{
    	printf("0です。\n");
    }
	
	return 0;
}

二つの条件を満たす

 入力した整数が「正の偶数」かを判定するプログラムを考えてみましょう。「正の偶数」であるためには、「正」であることと「偶数」であることの二つの条件を同時に満たしていることが必要です。
nestedif.c
#include <stdio.h>

int main(void)
{
	int n;
     
    printf("整数>> ");
    scanf("%d", &n);
 
    if (n>0) {			// 正である
        if (n%2==0) {		// 偶数である
        	printf("%dは、正の偶数です。\n",n);
        }
    }
	
	return 0;
}
 一方の条件を判定しその結果が「真」ならばもう片方の条件を判定します。もし内側のif文も「真」ならば二つの条件を満たしていることになります。if文の中にまたif文が登場する入れ子(ネスト)構造によって条件判定を実現しています。

expand_lessBack to TOP

論理演算、ORとANDとNOT

 前節では、二つもしくは三つの条件を判定をするために二つのif文を組み合わせました。しかし、複数の条件もその関係から、論理演算子を使うことで一つの条件にまとめることができます。ここでは、論理演算子OR、AND、NOTのそれぞれ意味と、それらを使った条件式の作り方について見ていきます。

OR条件

 入力した整数が「10未満もしくは3の倍数」かを判定するプログラムを考えてみましょう。この「もしくは」を表わす論理演算を論理和(OR)といい、記号||を使って表わします。
c5-5.c
#include <stdio.h>

int main(void)
{
	int n;
     
    printf("整数>> ");
    scanf("%d", &n);
 
    if (n<10 || n%3==0) {
        printf("%dは、10未満もしくは3の倍数です。\n",n);
    }
	
	return 0;
}
 条件Aと条件Bの論理和(OR)をベン図で表わすと下図のようになります。
OR

AND条件

 次に、入力した整数が「10以上でかつ5の倍数」かを判定するプログラムを考えてみましょう。この「かつ」を表わす論理演算を論理積(AND)といい、記号&&を使って表します。
c5-6.c
#include <stdio.h>

int main(void)
{
	int n;
     
    printf("整数>> ");
    scanf("%d", &n);
 
    if (n>=10 && n%5==0) {
        printf("%dは、10以上でかつ5の倍数です。\n",n);
    }
	
	return 0;
}
 二つの条件、条件Aと条件Bの論理積(AND)をベン図で表わすと下図のようになります。
AND

NOT条件

 入力した整数が「3で割り切れない数ではない」を判定するプログラムを考えます。この「ではない」を表わす論理演算を否定(NOT)といい、記号!を使って表わします。
c5-7.c
#include <stdio.h>

int main(void)
{
	int n;
	
	printf("整数>> ");
	scanf("%d", &n);

	if(!(n%3!=0)){
		printf("%dは、3で割切れない数ではない。\n", n);
	}	
	
	return 0;
}
NOT
論理演算子一覧
演算子説明記述例説明
&&論理積(かつ、and)a>-5 && a<5aは-5より大きくかつ5より小さい
||論理和(または、or)a<=-5 || a>=5aは-5以下または5以上
!否定(でない、not)!(a>-5 && a<5)aは-5より大きくかつ5より小さいのではない

3つ以上の値の比較は論理演算子を使う

 変数aの値が0より大きく10より小さい範囲にあることを数学では
0 < a < 10
と記述します。しかし、プログラムではこれをそのまま条件式として使うことはできません。なぜなら、数学における < は大小関係を示す記号ですが、プログラムでは比較演算子であり式は評価されるからです。この式においては、左から右に向かって順に評価されるので、以下の式の評価と同じに結果になります。
(0 < a) < 10
 例えば、変数aの値が11だとすれば、評価結果として「偽」が期待されます。ところが、まず左側の式 0<a から評価されるのでその結果は真、すなわち整数の1となります。次に式 1<10 が評価されるので、「真」と間違った評価されてしまうのです。
 正しい条件式は
a > 0 && a < 10
と、二つの条件式をANDで接続しなければなりません。

expand_lessBack to TOP

演習問題

  1. 整数を入力して0もしくは正の整数か負の数かをif〜else文を使って判定するプログラムです。空欄を埋めて完成させなさい。
  2. 例 ex2-1.c
    #include <stdio.h>
    
    int main(void)
    {
    	int a;
    
    	printf("整数>> ");
    	scanf("%d", &a);
    
    	[[空欄ア]] {
    		printf("0 もしくは 正の整数です。\n");
    	}
    	[[空欄イ]] {
    		printf("負の整数です。\n");
    	}
    
    	return 0;
    }
    
  3. 入力した整数が0であるかそうでないかをif〜else文を使って判定するプログラムです。空欄を埋めて完成させなさい。
  4. 例 ex2-2.c
    #include <stdio.h>
    
    int main(void)
    {
    	int a;
    
    	printf("整数>> ");
    	scanf("%d", &a);
    
    	[[空欄ア]] {
    		printf("0です。\n");
    	}
    	[[空欄イ]] {
    		printf("0ではありません。\n");
    	}
    
    	return 0;
    }
    	
  5. 評価を1〜3の3段階で入力して結果を星の数で表示するプログラムです。空欄を埋めて完成させなさい。
  6. ex2-3.c
    #include <stdio.h>
    
    int main(void)
    {
    	int n;
    
    	printf("評価(1−3)>>");
    	scanf("%d", &n);
    
    	[[空欄ア]] {
    		printf("★\n");
    	}
    	[[空欄イ]]  {
    		printf("★★\n");
    	}
    	else {
    		printf("★★★\n");
    	}
    
    	return 0;
    }
    
  7. 次のプログラムex2-4.cは、二つの整数を入力して大きい方の値を表示するプログラムです。[空欄ア]に入れるべき条件式を示しなさい。
  8. ex2-4.c
    #include <stdio.h>
    
    int main(void)
    {
    	int a,b;
    	
    	printf("整数a >> ");
    	scanf("%d",&a);
    	printf("整数b >> ");
    	scanf("%d",&b);
    
    	if ([[空欄ア]]) {
    		a = b;
    	}
    	printf("大きい方の値は、%dです。\n",a);
    		
    	return 0;
    }
    
  9. 次のプログラムex2-5.cは、入力した整数が5の倍数であるかを判定するプログラムです。[空欄イ]に入れるべき条件式を示しなさい。
  10. ex2-5.c
    #include <stdio.h>
    
    int main(void)
    {
    	int a;
    	
    	printf("整数a >> ");
    	scanf("%d",&a);
    
    	if ( [[空欄ア]]) {
    		printf("5の倍数ではありません。\n");
    	}
    	else {
    		printf("5の倍数です。\n");
    	}
    		
    	return 0;
    }
    
  11. 次のプログラムはex2-6.cは、yesと入力すると「yesですね。」、noと入力すると「noですね。」と表示するプログラムです。空欄を埋めて正しい結果が得られるようにしなさい。
  12. ex2-6.c
    #include <stdio.h>
    
    int main(void)
    {
    	[[空欄ア]];
    
    	printf("yes or no ? >>");
    	scanf("%c", &ch);
    
    	if (ch == [[空欄イ]]) {
    		printf("yesですね。\n");
    	}
    	if (ch == [[空欄ウ]]) {
    		printf("noですね。\n");
    	}
    
    	return 0;
    }
    
     ※ %cは文字を読み込むための変換指定子です。キーボードから文字列を入力しても読み込まれるのは先頭の1文字だけです。

  13. 年齢を入力して、20歳以上ならば「成人です。」、そうでなければ「未成年です。」と表示するプログラムex2-7.cを作成しなさい。

  14. 英語、数学、国語の各試験の得点を入力して、その平均点が60点以上なら「合格」、そうでなければ「不合格」と表示するプログラムex2-8.cを作成しなさい。

  15. 入力した整数が一桁の正の整数かを判定するプログラムです。空欄を埋めて完成させなさい。
  16. ex2-11.c
    #include <stdio.h>
    
    int main(void)
    {
    	int n;
    	
    	printf("整数>> ");
    	scanf("%d", &n);
    
    	if([[空欄ア]]) {
    		printf("1桁の正の整数です。\n");
    	}
    	else {
    		printf("1桁の正の整数ではありません。\n");
    	}
    
    	return 0;
    }
    
  17. 入力した整数が、−5より小さいか5より大きいかを判定するプログラムです。空欄を埋めて完成させなさい。
  18. ex2-12.c
    #include <stdio.h>
    
    int main(void)
    {
    	int n;
    	
    	printf("整数>> ");
    	scanf("%d", &n);
    
    	if([[空欄イ]]) {
    		printf("−5より小さいか、5より大きい整数です。\n");
    	}
    	else {
    		printf("−5以上5以下の整数です。\n");
    	}
    
    	return 0;
    }
    	

  19. 次のプログラムの実行結果を予測しなさい。
  20. ex2-13.c
    #include <stdio.h>
    
    int main(void)
    {
    	int a=15, b=15,c=20,d=30;
    
    	printf("b>=c --> %d\n", b >= c);
    	printf("c<d --> %d\n", c < d);
    	printf("a==15 || c!=20 --> %d\n", a==15 || c!=20);
    	printf("a==15 && b>=15 && d>15 --> %d\n", a==15 && b>=15 && d>15);
    	printf("b==0 && c!=0 || d<50 --> %d\n", (b==0 && c!=0) || d<50);
    
    	return 0;
    }
    
     C言語では論理演算の結果を整数の0と1を使って表わします。真ならば1で、偽ならば0になります。上記の演算結果を表示するプログラムを作成して確認してみましょう。

  21. 3つの整数を画面から入力して、小さい順に表示するプログラムex2-12を作成しなさい。

  22. 3つの整数を画面から入力して、大きい順に表示するプログラムex2-13を作成しなさい。

  23. 次のプログラムex2-14a.c と ex2−14b.c はどちらも、3つの整数を入力して最大値を求めるプログラムです。空欄を埋めて完成させなさい。
  24. ex2-14a.c
    #include <stdio.h>
    
    int main(void)
    {
    	int a,b,c,max;
    
    	printf("3つの整数(a,b,c)>> ");
    	scanf("%d,%d,%d", &a,&b,&c);
    
    	max = a;
    	[[空欄ア]] {
    		max = b;
    	}
    	[[空欄イ]] {
    		max = c;
    	}
    
    	printf("最大値は、%dです。\n",max);
    	return 0;
    }
    

    ex2-14b.c
    int main(void)
    {
    	int a,b,c;
    
    	printf("3つの整数(a,b,c)>> ");
    	scanf("%d,%d,%d", &a,&b,&c);
    
    	[[空欄ウ]] {
    		a = b;
    	}
    	[[空欄エ]] {
    		a = c;
    	}
    
    	printf("最大値は、%dです。\n" ,a);
    	return 0;
    }
    

  25. 身長と体重を入力してBMI(Body Mass Index)を求め、下記のいずれかの状態かを判定するプログラムex2-15.cを作成しなさい。BMIの値は、体重(Kg)/(身長(m)×身長(m))で求められる。
  26. 痩せすぎ 18.5未満
    普  通 18.5以上25未満
    太り気味 25以上30未満
    肥  満 30以上35未満

  27. 西暦年を入力して和暦年で表示するプログラムex2-16.cを作成しなさい。ただし、元号は明治、大正、昭和、平成のいずれかに対応するものとし、それ以外の年については「対応していません。」と表示するものとします。また、元号の切り替えは正確には月日によりますが、ここでは下記の表に従うものとします。
  28. 西暦1868年 明治1年
    西暦1912年 大正1年
    西暦1926年 昭和1年
    西暦1989年 平成1年


  29. 整数を入力して、3の倍数であるときは「Fizz」、5の倍数であるときは「Buzz」、15の倍数であるときは「Fizz Buzz」、それ以外のときは入力した数字を表示するプログラムex2-17.cを作成しなさい。

  30. 数字を入力して、「正か負か」、加えて「整数か小数か」、それとも「ゼロか」を判定するプログラムex2-18.c

  31. 三角形の各辺の長さを入力して、三角形が作れる場合はその面積を求め、そうでない場合は「三角形が作れません。」と表示するプログラムex2-19.cを作成しなさい。三角形が成立するための条件は、三辺の長さをそれぞれをa,b,cとすると、「a<b+c かつ b<c+a かつ c<a+b 」である。
    (ヘロンの公式)
     三角形の三辺の長さをそれぞれa、b、cとして、
    ヘロンの公式
    とすると、三角形の面積Sは、次式で求めることができる。
    ヘロンの公式
    (平方根の計算には、関数sqrt()が利用できます。ただし、ヘッダファイルmath.hをインクルードする必要があります。)


演習問題解答

OPEN ANSWER
  1. 空欄ア if (a>=0) 、空欄イ else

  2. 空欄イ if (a==0) 、空欄イ else

  3. 空欄ア if (n==1) 、空欄イ else if (n==2) 空欄ウ else

  4. 空欄ア b>a

  5. 空欄ア a%5

  6. 空欄ア char ch、 空欄イ 'y'、 空欄ウ 'n'

  7. 回答例 ex2-7.c
  8. code/2/ex2-7.c

  9. 回答例 ex2-8.c
  10. code/2/ex2-8.c
    補足)平均を小数点数を含む値として取り扱うために、変数の型をdouble型とした。また、その値を小数点以下1桁まで表示するために書式指定を .1f とした。

  11. 空欄ア n>0 && n<10

  12. 空欄イ n<-5 || n>5

  13. 回答 省略

  14. 回答 ex2-12.c
  15. code/2/ex2-12.c

  16. 回答 ex2-13.c
  17. code/2/ex2-13.c

  18. 回答 ア. if (b>max)  イ. if (c>max)  ウ. if( b>a && b>c) エ. else if ( c>a && c>b)

  19. 回答例 ex2-15.c
  20. code/2/ex2-15.c

  21. 回答例 ex2-16.c
  22. code/2/ex2-16.c

  23. 回答例 ex2-17.c
  24. code/2/ex2-17.c
    補足)「3の倍数でも5の倍数でもない」を表す条件式は、!(n%3==0 || n%5==0) としても良い。

  25. 回答例 ex2-18.c
  26. code/2/ex2-18.c

  27. 回答例 ex2-19.c
  28. code/2/ex2-19.c


expand_lessBack to TOP

確認テスト

理解度クイズ

  1. 変数aが50以上であるかを判定するための条件式は a=>50 である。正しい?正しくない?

  2. 変数aが0より大きくて10より小さいかを判定するための条件式は 10>a>0 ではなく、a < 10 && a > 0である。正しい?正しくない?

  3. 変数aの値が50の時、次のプログラムの実行結果はどうなる?
  4. 	if(a>50){
    		printf("X\n");
    	}
    	else if (a<50){
    		printf("Y\n");		
    	}
    	else{
    		printf("Z\n");
    	}
    

  5. 次は、4時から10時前までは「おはよう」、10時から17時前までなら「こんにちは」、17時から23時前までなら「こんばんは」、23時から4時前までは「夢の中」、それ以外は「エラー」と表示するプログラムです。正しい?正しくない?
  6. 	if(h>=23 || h<4){
    		printf("夢の中\n");
    	}
    	else if (h>=17){
    		printf("こんばんは\n");		
    	}
    	else if(h>=4) {
    		printf("おはよう\n");
    	}
    	else{
    		printf("エラー\n");		
    	}
    

  7. 次のプログラムの間違いを見つけよう。
  8. 	if (s=100) {
    		printf("満点でした。\n");
    	else {
    		printf("満点ではありませんでした。\n");
    	}
    

今週の提出課題

  • 課題1
  • 3科目の得点を入力して、その平均点が60点以上なら「合格」、そうでなければ「不合格」と表示するプログラム

  • 課題2
  • 2つの整数aとbを入力して、aがbの約数なら「aはbの約数です」、そうでなければ「aはbの約数ではありません」と表示するプログラム

  • 課題3
  • 西暦年を入力して閏年ならば「閏年です」、そうでなければ「閏年ではありません」と表示するプログラム。閏年となる条件は、「4で割り切れ、かつ100で割り切れない年」であるか、もしくは「400で割り切れる年」です。


  • [提出方法]
    1. ideone.comを利用して作成した課題プログラムのURLをCoursePowerへ提出のこと。
    2. 詳細はスライド「ideoneの使い方」参照のこと。

  • [評価について]
  • プログラムの内容の評価とは別に以下の要件を満たすことを評価の前提とする。
    1. C言語で記述されていること。
    2. ソースコードファイルのコンパイル結果に、ワーニングやエラーが出力されていないこと。
    3. 所定の実行結果が得られるていること。
    4. ソースコードは、インデントや適当な改行が施された見やすい状態であること。

  • [提出期限]
  • 2023年 4月24日(月)までとする。ただし、以降の提出も受け付ける。