コンピュータ基礎実験 第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
© Copyright 2024 ExpyDoc