第6回(5/26)パワーポイント

コンピュータ基礎実験 第6回
コンピュータープログラミング
(C言語)(4)
1.キーボード入力(復習)
2.条件分岐(if文)
「キーボード入力」、「算術関数」
の復習
コンピューターは、「キーボード」や「マウス」、
「タブレット」などからデータを入力することが
可能
C言語では、「データの入力」も、「関数」(入出
力関数)を利用して実現可能:「scanf()」
三角関数や指数関数など、数学で使う関数
(算術関数)の使用
「#include <math.h>」をソースに書く
算術関数ライブラリをリンク「-lm」(Eclipseが行う)
キーボード入力関数「scanf()」
変数型宣言
int a;
のあとに
scanf(”%d”, &a);
とすると,キーボードから入力した整数の値が
aに入力される.
注)「a」に「&」を付けるのをわすれるな!
3
• 2つ以上の数の場合も同様に
int a, b, c, …, ;
☜ 整数型の
変数の場合
printf(”2つの整数? ”);
scanf(”%d %d”, &a, &b);
・ 実数型なら ☜ 実数型の
変数の場合
float x;
printf(”x= ”);
scanf(”%f”, &x);
文字型変数
☟ の場合
文字型なら
char name[10];
printf(”Name: ”);
scanf(”%s”, name);
& は不要
4
■ 前回発展課題
課題 EX5-5: 三角形の3辺の長さa, b, cを与え,面積を求める
プログラム( EX5-5.c )を示せ.ただし,三角形の面積を与える
公式(Heronの公式)は既知とする.
Heronの公式
S = s(s - a)(s - b)(s - c)
ここで,平方根の計算は
where 2s = a + b + c
sqrt(…) とすればよい.
[ヒント] プログラムの最初に #include <math.h> を加えること
発展課題 EX5-6: 課題 5-5において,平方根の計算を正確に
計算するプログラムを示せ.( EX5-6.c )
[ヒント]変数をdouble a,b,c,…  scanf(“%lf,…,&a, …) 、
printf(“%1.15f…”,a)として下さい.
5
変数の型と表記
型
扱える範囲
printf(scanf)中の表記
文字型
char
-127 〜 128 (文字)
%c(文字), %d(値)
整数型
int
- 2147483648
〜 2147483647
%d
倍長整数型
long
- 9223372036854775808
%ld
〜 9223372036854775807
単精度浮動小数点型 有効数字6桁の実数
float
3.4E-38 〜 3.4E+38
%f
倍精度浮動小数点型 有効数字15桁の実数
double
1.7E-308 〜 1.7E+308
%lf (scanf中)
注)printfでは%lfは使わない
⇒間違える人が多いので使
えるように変更された
http://www.kijineko.co.jp/tech/superstition
s/printf-format-for-double.html
前回発展課題2 回答例
EX5-6.c
EX5-6.c:
#include <stdio.h>
#include <math.h>
int main(void)
{
double a,b,c,s;
printf(”三角形の3辺を入力: ”);
scanf(”%lf %lf %lf”,&a,&b,&c);
s=(a+b+c)/2;
s=sqrt(s*(s-a)*(s-b)*(s-c));
printf(”面積: %1.15f\n”,s);
return 0;
}
コンパイル: $ gcc -lm EX5-6.c (Eclipse が自動で行う)
7
s=sqrt(s*(s-a)*(s-b)*(s-c))
上式は「s」についての方程式でしょうか?
C言語では、「=」は数学での「=」(右辺と左辺が
等しい)とは意味が異なります
C言語での「=」は、「右辺の計算結果」を「左辺
の変数」に記憶させるという意味です(代入)
「x=2*x+1」: 数学では「x=-1」です
「x=1; x=2*x+1;」: C言語では「xには3が記憶されて
いる状態になっている」です
「x=x+1」を、数学とC言語で考えてみよう
条件分岐1(2重分岐:if文)
キーボードからの入力や、計算結果に応じて処
理内容を変える場合があります
テレビゲームでもあります
「スライムが仲間になりたそうにこちらをみている」
「仲間にしますか? はい/いいえ」
C言語では、「2重分岐」と「多重分岐」の2種類
が用意されています
2重分岐: 「if文」⇒2股に分かれる
多重分岐:「switch~case文」⇒3股以上に分かれる
判断と分岐
■ 2重分岐
…条件式により2分岐選択制御 [ if 〜 else]
 if 文
if (条件式)
文1;
else
文2;
条件式
(1)関係演算
… 2つの値の大小関係の比較
(2) 論理演算
… 条件を満たすか否かを判定
■ 多重分岐…番号による場合分け
 switch文 〜 case
次回
10
■ 1.関係係演算子
意味
等しい
より大きい
数学記号
C言語
=
==
条件式の書き方
>
>
より小さい
<
<
等しいか,
より大きい
≧
>=
等しいか,
より小さい
≦
<=
等しくない
≠
!=
(Ex.1) a+b = c
 a+b == c
(Ex.2) a+b ≧c
 a+b >= c
11
■ 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
(注) || よりも && の方が優先順位は高い. 同じ順位の間では左から順
12
に評価される.また,( ) でくくってあればその中が先に評価される.
例1:2分岐「偶数 or 奇数?」
条件:2で割
り切れる?
a%2==0
NO
YES
aは偶数
aは奇数
int a;
…
if (a%2==0){
printf(”aは偶数”);
}
else {
printf(”aは奇数”);
}
もし,else以下の文が省略され
どの条件も満たさないと,
何も実行しないで終了する.
(注)文が複数行になる場合は { } で囲む.
1行の文の場合は{ }は省略可能.
文のかたまりが見えやすいように,
先頭の文字の頭を下げる(インデント)とよい.
13
例2:入れ子の2分岐「正 or 負 or 0?」
条件1:0より
大きい?
a>0
YES
NO
条件2:0より
小さい?
a<0
NO
YES
aは正
aは負
aは0
int a;
…
if (a>0){
printf(”aは正”);
}
else{
if(a<0){
printf(”aは負”);
}
else{
printf(”aは0”);
}
}
(注)文が複数行になる場合は { } で囲む.
1行の文の場合は{ }は省略可能.
文のかたまりが見えやすいように,
先頭の文字の頭を下げる(インデント)とよい.
14
例題EX6-1:
コンピューターが「2つの実数a,bをいれてください: 」と出力
2数を入力する(スペースを開けて)
コンピューター:「和と差を計算(1を入力) 積と商を計算(1以外入力): 」
「1」を入力⇒和と差を出力
「1」以外を入力⇒積と商を出力
第4回:分割コンパイルの練習プロジェクト「EX4-4」と「EX4-5」を組み合わ
せたプログラムです。
EX4-4.c → EX6-1.c
EX4-4-1.c → EX6-1-1.c
EX4-5-1.c → EX6-1-2.c
のように3つのソースをコピーして、改造しよう。
15
EX6-1.c:
例題EX6-1 1/2
cが1のときbasiccalc2
EX6-1.c
それ以外のときbasiccalc1
#include <stdio.h>
void basiccalc1(float a, float b);
void basiccalc2(float a, float b);
int main(void)
{
float a,b;
int c;
if(c==1){
basiccalc2(a,b);
}
else{
basiccalc1(a,b);
}
別ファイルの「basiccalc1」
と「basiccalc2」を使う
printf(”2つの実数を入れてくださ

い: ”);
scanf(”%f %f”,&a,&b);
printf(”和と差を計算(1を入力)
積と商を計算(1以外入力): ”);
scanf(”%d”,&c);
return 0;
}
16
例題EX6-1 2/2:
EX6-1-1.c, EX6-1-2.c
EX6-1-1.c:
EX6-1-2.c:
#include <stdio.h>
/* 積と商の計算 */
#include <stdio.h>
/* 和と差の計算 */
void basiccalc1(float a, float b)
{
float c,d;
void basiccalc2(float a, float b)
{
float c,d;
c=a*b; d=a/b;
printf(”a=%f b=%f の時、”,a,b);
printf(”積%f 商%f\n”,c,d);
}
c=a+b; d=a-b;
printf(”a=%f b=%f の時、”,a,b);
printf(”和%f 差%f\n”,c,d);
}
17
例題EX6-1分割コンパイルの手順
(Eclipse が自動で行う)
• 「EX6-1.c」をコンパイル
$ gcc -c EX6-1.c ⇒ EX6-1.o
• 「EX6-1-1.c」をコンパイル
$ gcc -c EX6-1-1.c ⇒ EX6-1-1.o
• 「EX6-1-2.c」をコンパイル
$ gcc -c EX6-1-2.c ⇒ EX6-1-2.o
• 3つのオブジェクトファイルをリンク
$ gcc EX6-1.o EX6-1-1.o EX6-1-2.o ⇒ EX6-1.exe
18
課題EX6-2: 次のプログラムの動作を予測せよ。また、実際
にコンパイルして動作を確かめよ。(コピー&ペーストOK)
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int a;
printf("ちゃーちゃ ちゃちゃちゃちゃ
ちゃちゃちゃ ちゃちゃちゃ ちゃ\n");
sleep(2);
printf("ちゃーちゃ ちゃちゃちゃ ちゃ
ん\n\n");
sleep(3);
printf("「王様」ゆうしゃよ りゅうおうを
たおすのじゃ\n");
printf("1: たびにでる 2: たびにでな
い\n");
scanf("%d",&a);
if(a==1){
sleep(2);
printf("メタルスライムがあらわれた
\n");
printf("1: たたかう 2: にげる\n");
scanf("%d",&a);
if(a==1){
printf("ちゃららっ\n\n");
sleep(1);
printf("ゆうしゃのこうげき\n");
sleep(2);
printf("メタルスライムに25のダ
メージ\n\n");
sleep(2);
printf("メタルスライムのこうげき
\n");
sleep(2);
printf("ゆうしゃに35のダメージ
\n\n");
sleep(2);
printf("ゆうしゃはしんでしまった
\n\n");
sleep(2);
}
else{
printf("\nメタルスライムのあと なに
もであいませんでした\n\n");
sleep(2);
printf("\nゆうしゃはへいぼんないっ
しょうをおえました\n\n");
sleep(2);
}
}
else{
printf("\nゆうしゃはへいぼんないっ
しょうをおえました\n\n");
sleep(2);
}
printf("「王様」ゆうしゃよ しんでしま
うとはなさけない\n");
return 0;
}
注) sleep(n)は、n秒間なに
もしないで待つ関数
#include <unistd.h>が
必要
19
課題EX6-3: 「うるう年(閏年)」は,
西暦年数が
“400で割り切れる年,または,
4で割り切れかつ100で割り切れない年”
と定義されています.西暦年数を入力し,「****年はうるう年
です(ではありません).」というように出力するプログラムを
作成せよ.( EX6-3.c )
実行例として(1) 2016年 (2) 2015年 (3) 2000年 (4) 1999年
(5) 1900年
が,うるう年かどうか調べよ.
ヒント:「4で割り切れる」⇒「4で割った余りが0」
(補足)優先順位 • ||より&&
同じ順位では左から順に評価
• If( (A && B) || (C && D))
括弧内は優先
20
課題EX6-4:
二次方程式 ax2+bx+c=0 の解を具体的に出力するプログラムを
作れ.ただし
解が重解なら
 重解
x=…
解が2つの実解なら  相異なる実数解
x =…, …
解が複素数なら
 相異なる複素数解
x=… +…i
x=… -…i
のように表現せよ.( EX6-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> を書き加えること
21
ヒント
• 「x=2.400000+12.30000i」と表示させるには
float a=2.4,b=12.3;
printf(”x=%f+%fi”,a,b);
22
課題EX6-5: つぎのようなプログラムを作れ.
1. まず,品物の単価と購入数を入力する.
2. つぎに,消費税(8%)を含めた請求額を表示する.
ただし,端数は切り捨てるものとする.
3. 最後に,客の支払った額を入力して,足りていれば
おつりの額を,足りなければ不足額を出力する.
( EX6-5.c )
実行例として次の3つを含み,5つ程度の例を試みてみよ.
(1) 単価1000円,購入数3個,客の支払額5000円
(2) 単価1000円,購入数3個,客の支払額3000円
(3)単価5円,購入数3個,客の支払額100円
ヒント:整数型で計算すれば自動的に端数切捨てになります
23
■ 発展課題
発展課題EX6-6: キャラクターベースのロールプレイン
グゲームを作成せよ( EX6-6.c )
24
実習結果のレポート
• 3つのソースファイル「EX6-3.c」、「EX6-4.c」、
「EX6-5.c」を添付ファイルにしてメールを送って
ください。
• 宛先: [email protected]
• 件名:コンピューター基礎実験6
• 本文:感想および一言
25