数値変数・数式・書式付き入出力の適切な使い方を理解しよう. そして,単純な数値データ処理プログラムを作成してみよう.
いつもの通り,作業用ディレクトリを準備しよう:
$ cd $ mkdir c-0509 $ cd c-0509
データ処理プログラムの段取りの基本形は次の通り:
書式付き入力 scanf() を利用して, キーボードからデータを入力し, 入力されたデータを変数に格納する. なお,変数の利用には事前準備が必要であり, ソースの先頭付近で型と名前を宣言しておく.
コード例:
#include <stdio.h> // scanf() に必要
int main(void)
{
int num; // 整数型の変数 num を宣言
// 「後で num を使うよ,整数を代入できるよ」
double val; // 実数型の変数 val を宣言
// 「後で val を使うよ,実数を代入できるよ」
...
scanf("%d %lf", &num, &val);
// 最初に %d で整数,次に空白,最後に %lf で実数,
// というパターンでキーボードから入力してね.
// 変数 num に整数,val に実数が格納されるよ.
// 変数名の前「&」の付け忘れに注意!!
...
}
数式等を利用して,目的のデータ処理を実行する.
コード例:
...
int main(void)
{
double total;
...
total = num*val;
// かけ算 num*val を計算し,計算結果を変数 total へ代入してね.
...
}
計算結果のデータにも型があることに注意しよう.
書式付き出力 printf() を利用し, 端末画面に計算結果等を表示する.
コード例:
#include <stdio.h> // printf() に必要
int main(void)
{
...
printf("%d * %f = %f\n", num, val, total);
// 文字や数値を端末画面に表示してね.
// %d は整数 num,%f は実数 val とtotal の値に置き換わるよ.
...
}
printf() と scanf() の書式について, %f と %lf のように, 微妙な違いがあることに注意しよう.
なお,C言語の世界では, 整数データと実数データとは明確に区別されている. たとえば,整数 123 と実数 1.23×102 は互いに別物となる. 数値的に,ほぼ等しいかもしれないが,完全に一致するとは限らない.
また,取り扱い可能な数値の範囲に制限がある. 計算結果のオーバーフロー等に注意しよう.
int型の整数データ1個あたりの情報量は, 4 byte(16進数8桁)=32 bit(2進数32桁)であり, 表現可能な数値の範囲は 0 〜 232ー1 ≒ 約40億となる. ただし通常は,負数も使うので,範囲はー約20億 〜 +約20億となる.
ソースを編集:
$ vim int.c # エディタは何でも OK
#include <stdio.h>
int main(void)
{
int x, y, z; // 整数型の変数 x,y,z の宣言
while (1) { // 繰り返し
printf("整数2個 > ");
scanf("%d %d", &x, &y); // 入力
z = x * y; // 計算(かけ算)
printf("%d * %d = %d\n", x, y, z); // 出力
}
return (0);
}
コンパイルと実行:
$ cc int.c -o int
$ ./int
整数2個 > 35 100
35 * 100 = 3500 # そだねー
整数2個 > 3500 1000000
3500 * 1000000 = -794967296 # えっ??
整数2個 > [Ctrl]+[C] # 強制終了
double型の実数データ1個あたりの情報量は 8 byte, 数値範囲は±約1.0×10±308, 有効数字は15桁となっている.
double.c:
...
#include <stdio.h>
int main(void)
{
double x, y, z; // 実数型の変数 x,y,z の宣言
while (1) {
printf("実数2個 > ");
scanf("%lf %lf", &x, &y); // 入力
z = x / y; // 計算(わり算)
printf("%f / %f = %f\n", x, y, z); // 出力
}
return (0);
}
$ ./double 実数2個 > 1 3 1.000000 / 3.000000 = 0.333333 実数2個 > 2.0 1.41421356 2.000000 / 1.414214 = 1.414214 実数2個 > 1 0 1.000000 / 0.000000 = inf # inf は infinity...無限ね 実数2個 > 0 0 0.000000 / 0.000000 = -nan # nan って何?not a number...不定値,非数
(型の指定)
(幅の指定)
実験:書式指定をわざと間違えてみよう.format.c:
#include <stdio.h>
int main(void)
{
int x = 123;
double y = 123.45;
printf("正:\n");
printf("x = %d\n", x);
printf("y = %f\n", y);
printf("誤:\n");
printf("x = %f\n", x); // 整数型は %d のハズ
printf("y = %d\n", y); // 実数型は %f のハズ
return (0);
}
実行結果はどうなる?
変数の値を使用して何かを計算する場合, 事前に初期化(初期値を代入 or 入力)しておく必要がある.
実験:変数をわざと初期化せずに使ってみよう.var.c:
#include <stdio.h>
int main(void)
{
int x, y, z; // 初期化しないと...
printf("%d %d %d\n", x, y, z); // どんな値?
return (0);
}
ゴミ(無意味な値)が入っている. また,実行しなおす度に異なる結果となる.
実行例:
$ ./d2x 10進数 > 255 16進数 = FF 10進数 > 16 16進数 = 10 ...
要求仕様:次の動作を永久に繰り返す:
実行例:
$ ./x2dq 16進数を10進数に変換しなさい. 0x67 > 100 ☓ :正解は 103 です. 0xC6 > 198 ◯ 0x69 > 105 ◯ . . .
提出: