C言語のプログラミング (4)

コンピュータ基礎実験 第8回
コンピュータープログラミング
(C言語)(5)
1.条件分岐1(if文、復習)
2.条件分岐2(switch,case文)
条件分岐1(if文、復習)
キーボードからの入力や、計算結果に応じて処
理内容を変える場合があります
C言語では、「2重分岐」と「多重分岐」の2種類
が用意されています
2重分岐: 「if文」⇒2股に分かれる
多重分岐:「switch~case文」⇒3股以上に分かれる
判断と分岐
■ 2重分岐
…条件式により2分岐選択制御 [ if 〜 else]
 if 文
if (条件式)
文1;
else
文2;
条件式
(1)関係演算
… 2つの値の大小関係の比較
(2) 論理演算
… 条件を満たすか否かを判定
3
■ 1.関係係演算子
意味
等しい
より大きい
数学記号
C言語
=
==
条件式の書き方
>
>
より小さい
<
<
等しいか,
より大きい
≧
>=
等しいか,
より小さい
≦
<=
等しくない
≠
!=
(Ex.1) a+b = c
 a+b == c
(Ex.2) a+b ≧c
 a+b >= c
4
■ 2.論理演算子
A, B のそれぞれを条件式として
意味
A, Bの両者とも成立すれば 真
A, Bのどちらかが成立すれば
Aが成立しなければれば 真
真
名前
C言語での表現
論理積
AND
A && B
論理和
OR
A || B
否定
NOT
!A
(Ex.1) “x+y = c” と “z > 0” の両方が成立すれば真
 x+y == c && z > 0
(Ex.2) “0 < x < 100 ”  0 < x && x < 100
(Ex.3) “x = y = 1”  x == 1 && y == 1
(注) || よりも && の方が優先順位は高い. 同じ順位の間では左から順
5
に評価される.また,( ) でくくってあればその中が先に評価される.
「if文」の書き方(コツ)
If文は、カッコが多いので、先にカッコを書いてし
まうのがコツです。
カッコ類は左の例のようにそろえると
見やすいです(他のスタイルもあります)
if(){
}
else{
}
後から( )内に条件式、{ }内に文を書きます。
if(x>=0){
printf(”|x|=%f\n”,x);
}
else{
printf(”|x|=%f\n”,-x);
}
頭をそろえる(インデント)
•( )内に条件式: x>=0
•初めの{ }内に文1: printf(”|x|=%f\n”,x);
•次の{ }内に文2: printf(”|x|=%f\n”,-x);
前回課題7-4:
二次方程式 ax2+bx+c=0 の解を具体的に出力するプログラムを
作れ.ただし
解が重解なら
 重解
x=…
解が2つの実解なら  相異なる実数解
x =…, …
解が複素数なら
 相異なる複素数解
x=… +…i
x=… -…i
のように表現せよ.( ex7-4.c) 実行例として
(1) a=1, b=1, c=-2, (2) a=1, b=-2, c=1, (3) a=1,b=1, c=1
を試みよ.
(注) 平方根の計算が必要になるので #include<stdio.h> のつぎに
#include<math.h> を書き加えること
7
前回課題7-4の条件わけ
2次方程式は判別式「d=b*b-4*a*c」で解が分類
されます
「dが0か?」と「dが正か負か?」の2段階で条件
わけしてみます。
D=0?
No
一段階目
Yes
D>0?
No
二段階目
Yes
重解
2実解
2複素解
枠の準備
二段階の枠を先に準備して、それから条件を
入力します
if( ){
}
else{
if( ){
}
else{
}
}
if( d==0){
重解の時の文;
}
else{
if( d>0 ){
2実解の時の文;
}
else{
2複素解の時の文;
}
}
フローチャートとソース
フローチャートとプログラムソースは一対一に
対応しています
D=0?
No
一段階目
Yes
D>0?
No
二段階目
Yes
重解
2実解
2複素解
if( d==0){
重解の時の文;
}
else{
if( d>0 ){
2実解の時の文;
}
else{
2複素解の時の文;
}
}
複素解の表し方
複素解のとき、どうやって複素数を表せばいい
でしょう?
複素数:「実部」と「虚部」
「実部」+「虚部」 i
解の公式による実部と虚部
実部:e=-b/2/a、虚部:f=±sqrt(4*a*c-b*b)
「printf(”%f + %f i”,e,f);」
Ex7-4.c:
前回課題7-4回答例
ex7-4.c
#include <stdio.h>
#include <math.h>
int main(void)
{
float a,b,c,d;
printf("2次方程式の係数a, b, cをいれて
ください(ax^2+bx+c=0): ");
scanf("%f %f %f",&a,&b,&c);
d=b*b-4*a*c;
if(d==0){
printf("重解:\n x=%f\n",-b/2/a);
}
else{
if(d>0){
printf("相異なる実数解:\n
x=%f, %f\n",(-b+sqrt(d))/2/a,(-bsqrt(d))/2/a);
}
else{
printf("相異なる複素数解:\n
x=%f+%fi, %f-%fi\n",-b/2/a,sqrt(-d)/2/a,b/2/a,sqrt(-d)/2/a);
}
}
return 0;
}
12
条件分岐2(switch、case文)
多重分岐(3重以上)には、switch、case文を使
います
多重分岐は、2重分岐の多段化(例:2次方程式
の解ex7-4.c)でも可能ですが、見づらく、switch、
case文のほうが見やすくなる場合があります。
どちらを使っても結果は同じです。見やすい(慣
れている)方を使ってください。
switch、case文
switch 文
switch (式){
case 定数1: 文1;
break;
case 定数2: 文2;
break;
…………..
default: 文;
}
式の値が
定数1と等しければ 文1を実行
定数2と等しければ 文2を実行
…….
それ以外なら 文 を実行
(注) 1.case 1 など のあとにコロン(:)が必要.
2.breakに出会うとswitch{}から抜ける.breakがないとそれ以下の文を実行する.
3.どれとも一致しなければdefault (省略することも可能)
14
switch 文
/* ex. 8-1 */
#include <stdio.h>
int main(void)
{
int n;
switch (式){
case 定数1:
文1;
break;
case 定数2:
文2;
break;
…………..
default: 文;
}
printf("曜日の番号 (1…7) を入力してください:");
scanf("%d", &n);
printf("この日は何曜日?: ");
switch(n){
case 1: printf(" 月曜日 \n");
break;
case 2: printf(" 火曜日 \n");
break;
case 3: printf(" 水曜日 \n");
break;
----(中略) ----case 7: printf(" 日曜日 \n");
break;
default: printf("入力番号が正しくありません.
\n");
}
}
15
(注)
switch 文は
文字(char型)
でも受けられる
/* ex. 8-1a */
#include <stdio.h>
int main(void)
{
char x;
printf(“曜日の記号 (a…g) を入力してください:");
scanf("%c", &x);
printf("この日は何曜日?: ");
switch(x){
case 'a': printf(" 月曜日 \n");
break;
case 'b': printf(" 火曜日 \n");
break;
case 'c': printf(" 水曜日 \n");
break;
----(中略) ----case 'g': printf(" 日曜日 \n");
break;
default: printf("入力記号が正しくありません. \n");
}
注意!
}
16
(注)
switch 文では
複数のcase句
をまとめることも
できる
switch (式){
case 定数1:
case 定数2:
文1;
break;
case 定数3:
文3;
break;
…………..
default: 文;
}
/* ex. 8-1b */
#include <stdio.h>
int main(void)
{
int n;
printf("曜日の番号 (0=日,1=月,2=火,…,6=土)
を入力してください:");
scanf("%d", &n);
printf("この日は何曜日?: ");
switch(n){
case 1:
case 2:
case 3:
case 4:
case 5: printf(" 平日です. \n");
break;
case 6:
case 0: printf(" 週末です. \n");
break;
default: printf("入力番号が正しくありませ
ん.\n");
}
17
return 0;
例題8-2: 電卓プログラム1
2実数a, bを入力し、その後、1-4の整数を入力し、1なら和、2なら
差、3なら積、4なら商を計算するプログラムを作れ( ex8-2.c )
#include <stdio.h>
int main(void)
{
float a,b;
int c;
printf("2つの実数a, bを入力してください:
");
scanf("%f %f",&a,&b);
printf(" a=%f, b=%f\n",a,b);
printf(“計算の種類(1:和、2:差、3:積、4:
商): ");
scanf("%d",&c);
switch(c){
case 1: printf("%f+%f=%f\n",a,b,a+b);
break;
case 2: printf("%f-%f=%f\n",a,b,a-b);
break;
case 3: printf("%f*%f=%f\n",a,b,a*b);
break;
case 4: printf("%f/%f=%f\n",a,b,a/b);
break;
default: printf("入力が間違っています
\n");
}
return 0;
}
18
課題8-3: 電卓プログラム2
「12.3 + 45.6」と入力すると、和、差、積、商を計算するプログラム
を作れ。数字と演算子の間はスペースで区切るとし、演算子として
は「+」「-」「*」「/」の4つがあるとする。( ex8-3.c )
•「演算子を表す文字」はchar型変数に記録することができる
•「1 2 a」 なら scanf(”%f %f %c”,&a,&b,&c); (a,b float型、c char型)
•文字は「’」(クオート)で囲むことをわすれるな
19
課題8-4:
今年の月と日を入力し、それが今年の1月1日から数えて何日目か
を求めるプログラムを作成せよ. ただし、うるう年は考えないとする。
( ex8-4.c )
ヒント: 前月までの月の合計数に日を加えればよい.
(5月29日なら1月~4月の日の合計(31+28+31+30)に29を
加えればよい)
課題8-5:
今年(2015年)の1月1日は木曜日でした.今年の月と日を入力し,そ
れが何曜日であるかを出力するプログラムを作成せよ.
( ex8-5.c )
ヒント:1月1日から数えて何日目かを7で割ったあまりを利用
1月1日(1日目)が木曜なら、1月2日(2日目)は何曜日?
20
発展課題8-6:
知りたい年月日がその年の元日(これを第1日目とする)から数えて
何日目で,大晦日まで何日残っているかを計算するプログラムを作
成せよ.ただし,考えている年がうるう年であるか,そうでないかに
より計算を区別するものとする..( ex8-6.c )
21
実習結果のレポート
• 3つのソースファイル「ex8-3.c」、「ex8-4.c」、
「ex8-5.c」を添付ファイルにしてメールを送って
ください。
• 宛先: [email protected]
• 件名:コンピューター基礎実験8
• 本文:感想および一言
22