本課題は渡辺先生の作成した「応用理工情報処理」(金曜クラス)のテキストをもとに一部改訂したものです。
[渡辺先生のオリジナル版ページ] (参考)
渡辺先生に感謝!
今日から本格的にC言語の学習を行います。 今日学習することは、
整数および実数の表示方法、
整数および実数の四則演算、
整数および実数のキーボードからの入力方法、です。
まず、テキスト p. 11 の List 1-8 のプログラムを動かしてみましょう。下記のプログラムをコンパイル・実行してみて下さい。(コンパイル・実行の仕方はこの講義の第一回を参照。)
/* 二つの変数に整数値を格納して表示 */
#include <stdio.h>
int main(void){
int vx, vy;
/* vxとvyはint型の変数 */
vx = 57; /* vxに57を代入 */
vy = vx + 10; /* vyにvx+10を代入 */
printf("vxの値は%dです。\n", vx); /* vxの値を表示 */
printf("vyの値は%dです。\n", vy); /* vyの値を表示 */
return (0);
}
ここで注目して欲しいのは 変数 です。変数は、数値などを格納するコンピュータメモリ-上の領域です。値を格納するための架空の「箱」というイメージですね。ここで言う「値」には様々な形や大きさが有ります。例えば、整数、小数点数などです。文字や文字列も「値」として考えます。
値をメモリに格納する際には、「箱」を確保する必要があります。また、箱を確保する際、どんな値でも入るような大きな箱を常に百歩するのはメモリの無駄になります。そこで、箱に格納する値のタイプを事前に決め、それに合わせた箱を確保します。
ここで、箱、というのが「変数」。値のタイプを「データ型」もしくは「変数型」、そして、箱を確保するをこと「変数宣言」といいます。上のプログラムでは
int vx, vy;
という文が変数宣言です。ここで、vx, vy は変数の名前、int は「変数型」を指定するための「宣言子」です。この例では、整数型の値を格納するための箱を2つ用意し、それぞれに vx, vy という名前を付けています。
変数を使用するには、プログラムの最初で宣言しておく必要があります。(正確には、{ } で囲まれたコードブロックの最初で宣言します。
[Advanced Topic]
変数宣言の場所はC言語とC++で違いがありまる。C++では使用する前であればどこでも宣言文を書くことができます。一般的には拡張子を.cとするとC言語コードとしてコンパイルされ、.cppとするとC++言語としてコンパイルされます。
以下の文は vx という変数に57という値を代入しています。
vx = 57;
ここで、「=」は「等号」ではなく「代入演算子」といいます。代入演算子は = の右にある値を左側の変数に代入するための命令です。(厳密には「この変数の名前で確保されたメモリに右側の値を書き込む」ことになります。)
文字列 とその表示
C言語ではダブルクォーテーション " で囲んで囲まれた文字は「文字列」データとして扱われます。例えば "mojiretsu" というのは mojiretsu という値を持った「文字列」です。
printf("vxの値は%dです。\n", vx);
は文字列を画面(コンソールウィンドウ)に表示するための命令です。%d の部分は、続く実引数(ここではvx) を10進数で表示せよ、という「書式」(format) を指示するための変換指定です。\n は改行を意味します。書式の詳細はテキスト p. 354、13-3節の「printf 関数と scanf 関数」を参照してください。
キーボードから読み込みを行う以下のプログラムをコピーして動かしてみて下さい。(テキスト p. 14, List 1-11)
/* 読み込んだ整数の値を表示して確認 */
#include <stdio.h>
int main(void) {
int no;
printf("整数を入力してください:");
scanf("%d", &no); /* 整数値を読み込む */
printf("あなたは%dと入力しましたね。\n", no);
return (0);
}
ここでは新しい関数 scanf("%d", &no) に注目してください。この関数は、キーボードから整数を読み込んでその値を変数 noに格納します。%d はprintf の書式と同じで、キーボードから読み込まれる値の書式を指定しています。(詳細は テキスト 358ページ)
no の前の & に注意してください。& はアドレス演算子といって、変数 no の頭に & をつけた &no は変数 no の「メモリアドレス」を示します。メモリアドレスとは、その変数の値が保存されている「メモリ上の位置」です。つまり scanf 関数は以下の様なことをする関数であるといえます。
キーボードから受け取った値を書式に基づいて解釈します。これにより、「値」はコンピュータで読み書きできるような2進数の表記に変換されます。
その2進数で表記された値を、指定されたメモリアドレスで指定さればメモリ状の場所に書き込みます。
つまり、適切に書式とメモリアドレスが指定されていれば、scanf 関数によってキーボードから入力した値を変数に書き込める、ということです。
この時、1 の書式に誤りがあれば値が間違った値に変換されてしまいますし、2 のアドレス指定に誤りがあれば値を保存したい変数に値が保存できません。気をつけて下さい。
2つの整数を読み込んで、その和・差・積・商・剰余を表示する次のプログラム(テキストp. 22, List 2-1)を動かしてみましょう。
/* 読み込んだ二つの整数値の和・差・積・商・剰余を表示 */
#include <stdio.h>
int main(void) {
int vx, vy;
puts("二つの整数を入力してください。");
printf("整数vx:");
scanf("%d", &vx);
printf("整数vy:");
scanf("%d", &vy);
printf("vx + vy = %d\n", vx + vy);
printf("vx - vy = %d\n", vx - vy);
printf("vx * vy = %d\n", vx * vy);
printf("vx / vy = %d\n", vx / vy);
printf("vx %% vy = %d\n", vx % vy);
return (0);
}
このプログラムで注意することは以下の点です。
整数同士の割り算では小数点以下は切り捨てられる。
剰余演算子% 例えば3 % 2の値は1となる。
int 型(整数型)とdouble 型(倍精度浮動小数点型)に関するテキスト p. 29 List 2-6を動かしてみましょう。
/* 整数と浮動小数点数 */
#include <stdio.h>
int main(void) {
int nx; /* 整数 */
double dx; /* 浮動小数点数 */
nx = 9.99;
dx = 9.99;
printf(" int 型変数nxの値:%d\n", nx); /* 9 */
printf(" nx / 2:%d\n", nx / 2); /* 9 / 2 */
printf("double型変数dxの値:%f\n", dx); /* 9.99 */
printf(" dx/2.0:%f\n", dx / 2.0); /* 9.99 / 2.0 */
return (0);
}
これまでは int 型(整数型)だけを使ってきましたが、ここであらたに実数を扱うための double 型(倍精度浮動小数点型)が出てきました。違う部分を見てみましょう。
宣言では、double というキーワード(型宣言子)を使う。
書式変換指定では %f を使う
割り算では小数点以下も計算できる。
テキスト p.31 List 2-7 のプログラムを考えてみましょう。
/* 二つの実数値を読み込んで和・差・積・商を実数で表示 */
#include <stdio.h>
int main(void) {
double vx, vy; /* 浮動小数点数 */
puts("二つの数を入力してください。");
printf("実数vx:");
scanf("%lf", &vx);
printf("実数vy:");
scanf("%lf", &vy);
printf("vx + vy = %f\n", vx + vy);
printf("vx - vy = %f\n", vx - vy);
printf("vx * vy = %f\n", vx * vy);
printf("vx / vy = %f\n", vx / vy);
return (0);
}
このプログラムで注意する点は、scanf 関数の変換指定 %lf です。詳しく言うと、実数型には float(単精度浮動小数点)とdouble(倍精度浮動小数点)があります。%f は float 型用であり、double 型はそれよりも long な実数を扱うので l つけて %lf です。
演算を行うと、オペランド(演算の対象となる値や変数のこと)の型によって暗黙の型変換が行われることがあります。これをみるために、テキストp. 33 List 2-8 のプログラムを動かして見ましょう。
/* 型と演算について確認する */
#include <stdio.h>
int main(void) {
int n1, n2, n3, n4; /* 整数 */
double d1, d2, d3, d4; /* 浮動小数点数 */
n1 = 5 / 2; /* n1 ← 2 */
n2 = 5.0 / 2.0; /* n2 ← 2.5 (代入時に小数点以下切り捨て) */
n3 = 5.0 / 2; /* n3 ← 2.5 (代入時に小数点以下切り捨て) */
n4 = 5 / 2.0; /* n4 ← 2.5 (代入時に小数点以下切り捨て) */
d1 = 5 / 2; /* d1 ← 2 */
d2 = 5.0 / 2.0; /* d2 ← 2.5 */
d3 = 5.0 / 2; /* d3 ← 2.5 */
d4 = 5 / 2.0; /* d4 ← 2.5 */
printf("n1 = %d\n", n1);
printf("n2 = %d\n", n2);
printf("n3 = %d\n", n3);
printf("n4 = %d\n\n", n4);
printf("d1 = %f\n", d1);
printf("d2 = %f\n", d2);
printf("d3 = %f\n", d3);
printf("d4 = %f\n", d4);
return (0);
}
ここで注意する点は、int / int (整数 ÷ 整数)では結果も int であり小数点以下が切り捨てられるのに対して、int / doubleや double / int では暗黙の型変換が行われ int 型が double 型に変換されてから演算が行われるため、結果は double 型となる点です。ただしその値を int 型の変数へ代入すると、代入された値は小数点以下が切り捨てられた int 型となります。
変数型・値の型の変換は「キャスト演算子」を用いて明示的に行うことも出来ます。テキストp. 35の List 2-10 を見てみましょう。
/* 二つの整数値を読み込んで平均値を実数で表示(キャスト) */
#include <stdio.h>
int main(void) {
int na, nb;
puts("二つの整数を入力してください。");
printf("整数A:");
scanf("%d", &na);
printf("整数B:");
scanf("%d", &nb);
printf("それらの平均は%fです。\n", (double)(na + nb) / 2); /* キャスト */
return (0);
}
(na + nb) / 2 の式は、na, nb が int 型なのでこのままでは小数点以下が切り捨てられますが、 計算する前にキャスト演算子(double) でdouble型に変換してやると小数点以下も計算されます。
数値出力の変換指定では、出力幅を指定するものや小数点以下の桁数指定などがあります。テキスト p. 37 の List 2-12 を見てみましょう。
/* 整数と浮動小数点数を書式化して表示 */
#include <stdio.h>
int main(void) {
printf("[%d]\n", 123);
printf("[%.4d]\n", 123);
printf("[%4d]\n", 123);
printf("[%04d]\n", 123);
printf("[%-4d]\n\n", 123);
printf("[%d]\n", 12345);
printf("[%.3d]\n", 12345);
printf("[%3d]\n", 12345);
printf("[%03d]\n", 12345);
printf("[%-3d]\n\n", 12345);
printf("[%f]\n", 123.13);
printf("[%.1f]\n", 123.13);
printf("[%6.1f]\n\n", 123.13);
printf("[%f]\n", 123.13);
printf("[%.1f]\n", 123.13);
printf("[%4.1f]\n\n", 123.13);
return (0);
}
たとえば、%4d は最小4桁の幅での整数出力、 %4.1f は小数点以下1桁かつ最小4桁の幅での実数出力です。
次の課題をのプログラムを作成し、担当教官もしくはTAに確認してもらうこと。(確認は 本日のもう一つのユニット(Unit 3)とまとめてで大丈夫です。)
身長 (cm) を double 型の値として読み込んで、(身長-100)×0.9で計算される標準体重 (kg)を小数点以下2桁まで表示するプログラムを作成せよ。 (変換指定は %.2f である。) 出力は以下に示す例のとおりにすること。
------ 実行例 -----
身長は何cmですか:170.5
標準体重は63.45 kgです。