第3回 プログラミング入門 演習(解答)
【演習の注意事項】を良く読んで解答してください
【演習室1〜6以外で課題を解く場合の注意】も参考にしてください
Cプログラミングの初歩
--( はじめてのCプログラミング)---
(その2)
【主な内容】
- 入力文
- 浮動小数点型の変数と演算
- キャスト(型変換)
初級レベル
(A-1)
以下はプログラムの一部を抜きだしたものである。変数 a の最終的な値は
何になるか考えて、予想した結果を ex03a1.txt に記入しなさい。
また、#include, printf 等必要な命令を補って完全なプログラム ex03a1.c を作成して確認しなさい。
但し、このプログラムファイルは提出コマンドで提出されません。
ファイル名:ex03a1.txt、ex03a1.c
解答例
aの値は最終的に22である。
以下に,変数aの変化を示す。
int a = 10; /* a = 10 */
a = a + 1; /* a = 10 + 1 = 11 */
a = a + a; /* a = 11 + 11 = 22 */
確認用プログラム例
#include <stdio.h>
main()
{
int a = 10;
a = a + 1;
a = a + a;
printf("a=%d\n", a);
}
実行結果
a=22
(A-2)
以下はプログラムの一部を抜きだしたものである。変数c1とc2の値はそれぞれ何になるか予想した
結果と、c1 と c2 とに違いが生じる場合はその理由を、ex03a2.txt に記入しなさい。
また、#include, printf 等必要な命令を補って完全なプログラム ex03a2.c を作成して確認しなさい。
但し、このプログラムファイルは提出コマンドで提出されません。
ファイル名: ex03a2.txt、ex03a2.c
解答例
c1は5.5
c2は5.0 (int)aの処理で2.5が2になってしまう。
確認用プログラム例
#include <stdio.h>
main()
{
float c1, c2;
int b = 3;
float a = 2.5;
c1 = a + b;
c2 = (int)a + b;
printf("c1=%f, c2=%f\n", c1, c2);
}
実行結果
c1=5.500000, c2=5.000000
(A-3)
以下はプログラムの一部を抜きだしたものである。
変数 c1、c2、c3 の値は何になるか予想した結果と c1 と c2 と c3 とに違いが生じる場合はその理由を、ex03a3.txt に記入しなさい。
また、#include, printf 等必要な命令を補って完全なプログラム ex03a3.c を作成して確認しなさい。
但し、このプログラムファイルは提出コマンドで提出されません。
ファイル名: ex03a3.txt、ex03a3.c
解答例
c1=2 b/aの結果はint型になるため,整数部分だけが残る
c2=2.5 (float)bがfloat型のため,(float)b/aの結果がfloatになる。
尚,b/(float)aでも,同様な結果である。
c3=2.5 (float)b/(float)aは,(float)b/aと同じ効果である。
冗長に見えるが,意図がはっきりしており,可読性の観点からは悪くない。
確認用プログラム例
#include <stdio.h>
main()
{
float c1, c2, c3;
int b = 5;
int a = 2;
c1 = b/a;
c2 = (float)b/a;
c3 = (float)b/(float)a;
printf("c1=%f, c2=%f, c3=%f\n", c1, c2, c3);
}
実行結果
c1=2.000000, c2=2.500000, c3=2.500000
(A-4)
以下のプログラムはコンパイルは正常に行なわれますが、入力したものとは全くちがう数値が
表示されます(実行時エラーが発生することもあります)。
このプログラムのファイル名を ex03a4.c として作成し、コンパイル・実行しなさい。
そして、実行結果と異常動作(もしくはエラー)の原因がどの命令のどこにあったかを ex03a4.txt に
記述すると共に ex03a4.c を正常動作するように修正しなさい。
なお、提出ファイルは ex03a4.txt と修正後の ex03a4.c の2つになります。
ファイル名: ex03a4.c、ex03a4.txt
解答例
・デタラメな数値が出た場合の実行例
% ./a.out
整数値を入力して下さい: 12
a=-16799680
・実行時エラーが出た場合の実行例
% ./a.out
整数値を入力して下さい: 12
Segmentation Fault
プログラムの問題点と修正例
#include <stdio.h>
main()
{
int a;
/* 修正前,変数aに記号&が抜けている scanf("%d",a); */
printf("整数値を入力して下さい:");
scanf("%d",&a);
printf("a=%d\n",a);
}
(A-5)
以下は一辺の長さを整数で入力し、正方形の面積を求めるプログラムですが、
正常に動作しません。 正しく動作するように修正して提出しなさい。
ファイル名: ex03a5.c
解答例
(1)scanf("%d",&x)が正解。%fは整数変数xへのキー入力には使えない
(2)%fは整数変数の出力には使えないので、
printf("1辺の長さが%dの正方形の面積は%dです\n",x,area);
とするか、あるいは変数areaの値をfloatに変換して%fにあわせて、
printf("1辺の長さが%dの正方形の面積は%fです\n",x,(float)area);
でも正解。
中級レベル
(B-1)
scanf()関数で2つの実数をキーボードから読み込み、四則演算を行うプログラムを作りなさい。
なお、変数はすべて浮動小数点型とする。
ファイル名: ex03b1.c
[実行例] (浮動小数点演算では、丸め誤差の分だけ実行例と
一致しない場合もあります。)
% ./a.out
2つの実数を入力してください : 55.5 5.0
和 = 60.500000 差 = 50.500000
積 = 277.500000 商 = 11.100000
%
解答例
#include <stdio.h>
main()
{
float hensu1, hensu2; /* 浮動小数点型変数の定義 */
float wa, sa, seki, sho; /* 浮動小数点型変数の定義 */
printf("2つの実数を入力してください : ");
scanf("%f %f", &hensu1, &hensu2); /* hensu1,2に実数値を入力 */
wa = hensu1 + hensu2; /* 加算 */
sa = hensu1 - hensu2; /* 減算 */
seki = hensu1 * hensu2; /* 乗算 */
sho = hensu1 / hensu2; /* 除算 */
printf("和 = %f 差 = %f\n", wa,sa); /* 加算と減算結果の出力 */
printf("積 = %f 商 = %f\n", seki, sho); /* 乗算と除算結果の出力*/
}
(B-2)
円の面積と円周の長さを求める問題である。
円の半径rをキーボードから読み込み、面積と円周の長さを求めるプログラムを作りなさい。
なお、円周率は3.14159、半径は実数、単位はcmとし小数点以下も省かずに出力しなさい。
ファイル名:ex03b2.c
[実行例] (浮動小数点演算では、丸め誤差の分だけ実行例と一致しない場合もあります。)
% ./a.out
円の半径をcmで入力してください : 7.5
円の面積は 176.714447 平方cmです
円周の長さは 47.123852 cmです
%
解答例
#include <stdio.h>
main()
{
float r,pai,menseki,enshu;
pai=3.14159;
printf("円の半径をcmで入力してください:");
scanf("%f",&r);
menseki=r*r*pai;
enshu=2*pai*r;
printf("円の面積は %f 平方cmです。\n",menseki);
printf("円周の長さは %f cmです。\n", enshu);
}
(B-3)
商品の本体価格(整数:円)と消費税率(整数:%)を入力すると、税込みの価格が出力されるプログラムを書きなさい。
ただし、本体価格と消費税率を入れるための変数は整数(int)型とする。また、税込み価格は小数点以下も省かずに出力すること。
(例えば、10円で税5%だと10.5円)
ファイル名: ex03b3.c
[実行例]
% ./a.out
本体価格, 消費税率を入れてください
1990 5
税込みの価格: 2089.500000 円
%
解答例
#include <stdio.h>
main()
{
int hontai, zeiritu;
float zeikomi;
printf("本体価格, 消費税率を入れてください\n");
scanf("%d%d", &hontai, &zeiritu);
zeikomi = (float)hontai*(1.0 + (float)zeiritu/100.);
printf("税込みの価格: %f 円\n", zeikomi );
}
上級レベル
(C-1)
重み付き合計と平均(加重平均)
国語、数学、英語、理科、社会の点数と
それに対する重みを入力すると5教科の
重み付き合計点と重み付き平均点を出力する
プログラムを作りなさい。
なお、5教科の点数と重みは整数、重み付き
平均点は実数とし、重み付き平均点を求める
ときにキャストを用いなさい。また、実験的に
キャストをはずしたときにどのような結果に
なるかも試し、その結果をプログラムにコメント
として書きなさい。最終的な提出ファイルは
キャスト付きのものとします。
ファイル名: ex03c1.c
【重み付き合計と平均について】
総合成績として、例えば国語と数学のうち、
どちらかの点数について重点をおきたい場合、
それぞれの科目に対して重みというパラメータを
導入して加重平均を算出する。重み付き合計と
重み付き平均(加重平均)は以下のように求められる。
・重み付き合計点 = 国語の点数 * 国語の重み + 数学の点数 * 数学の重み
・加重平均 = 重み付き合計点 / ( 国語の重み + 数学の重み )
[実行例] (浮動小数点演算では、丸め誤差の分だけ実行例と一致しない場合もあります。)
% ./a.out
国語の点数と重みを入力してください : 74 1
数学の点数と重みを入力してください : 83 2
英語の点数と重みを入力してください : 77 2
理科の点数と重みを入力してください : 63 2
社会の点数と重みを入力してください : 50 1
5教科の重み付き合計点は 570 点で、重み付き平均点は 71.250000 点です。
%
解答例
#include <stdio.h>
main()
{
int koku, suu, ei, ri, sha;
int w_koku, w_suu, w_ei, w_ri, w_sha;
int goukei;
float heikin;
printf("国語の点数と重みを入力してください : ");
scanf("%d %d", &koku, &w_koku);
printf("数学の点数と重みを入力してください : ");
scanf("%d %d", &suu, &w_suu);
printf("英語の点数と重みを入力してください : ");
scanf("%d %d", &ei, &w_ei);
printf("理科の点数と重みを入力してください : ");
scanf("%d %d", &ri, &w_ri);
printf("社会の点数と重みを入力してください : ");
scanf("%d %d", &sha, &w_sha);
goukei = koku*w_koku + ei*w_ei + suu*w_suu + ri*w_ri + sha*w_sha;
heikin = (float)(goukei) / (w_koku+w_suu+w_ei+w_ri+w_sha);
printf("5教科の重み付き合計点は %d 点で、平均点は %f 点です。\n", goukei, heikin);
}
(C-2)
三角形の3辺の長さを入力し、三角形の面積を求める
プログラムを作りなさい。ただし、変数の型は全て
浮動小数点型を使用しなさい。
ファイル名: ex03c2.c
【ヘロンの公式】
三角形の3辺の長さa, b, cが与えられたとき、
その面積areaは次のヘロンの公式を用いて求めることができる。
実行例:
% ./a.out
三角形の3辺を入力して下さい -> 3.0 4.0 5.0
3辺の長さ : 3.000000,4.000000,5.000000 面積 : 6.000000
% ./a.out
三角形の3辺を入力して下さい -> 5.0 6.0 7.0
3辺の長さ : 5.000000,6.000000,7.000000 面積 : 14.696939
%
解答例
#include <stdio.h>
#include <math.h>
main()
{
float a, b, c, s, area;
printf("三角形の3辺を入力して下さい -> ");
scanf("%f %f %f", &a, &b, &c);
s = (a+b+c)/2;
area = sqrt(s*(s-a)*(s-b)*(s-c));
printf("3辺の長さ : %f,%f,%f 面積 : %f\n",a,b,c,area);
}
(C-3)
整数nをキー入力し、1+2+3+・・・・+n の和vを計算するプログラムを作りなさい。変数は全てint型を使用しなさい。
また、下記実行例2を踏まえてのコメントも記述すること。
ファイル名:ex03c3.c
利用する公式:

[実行例1]
% ./a.out
nを入力してください 4
v=10
ちなみに、以下のように大きなnを入力すると計算結果がおかしくなる。
[実行例2]
% ./a.out
nを入力してください 65535
v=-32768
上記結果の理由を,プログラムファイルの中に,コメントとして追加してください。
解答例
#include <stdio.h>
main()
{
int n;
int v;
printf("nを入力してください");
scanf("%d", &n);
v = (n + 1)*n/2;
printf("v=%d\n", v);
}
/*
大きなnで計算結果がおかしくなる理由は以下の通りである。
int型変数vが表現できる整数は,2147483647までです。
nが大きくなると,式 (n + 1)*n/2 の計算結果が大きすぎて,
vで表現できなくなってしまう(オーバーフロー)。
*/
何か疑問や間違いがあれば以下に連絡して下さい。
プログラミング入門演習問題担当(prog0)