プログラミングおよび演習 NO.2 |
変数 |
先週はコンピュータに電卓の働きをさせるために、数値定数を用いた数式の計算結果を表示するプログラムを習いました。しかし、複雑で長い計算式や、同じ公式を用いた計算を何度も繰り返す場合、演算内容が一目で分かるようにする、などの要求を考えると、もっと使いやすいプログラムに改良する必要があります。 始めに、
sum=a+b;
の式に従って、2つの数の和を求めて画面表示するプログラムを考えます。例として、a=1.0, b=2.0の場合は、先週習ったように、
printf("sum=%e\n",1.0+2.0);
とすることにより実現できます。同じ計算を、今週は変数を使って、
a=1.0;
b=2.0;
sum=a+b;
printf("sum=%e\n",sum);
のように書くことにします。このほうがよりプログラムらしくなります。
さて、上記のプログラムでは、a,b,sumの3つの変数を使っています。変数は、コンピュータのメモリ領域に任意の名前を付けて(名前の付け方の規則は後で説明します)、その名前のメモリ領域にデータを格納するために使います。ちょうど、電卓のメモリ演算機能と同じです。
この時、変数の型によってデータの格納の仕方が異なることに注意する必要があります。変数の型には、大きく分けて数値変数と文字変数がありますが、前者の数値変数はさらに、実数変数と整数変数の2つに分けられます。先週、数値定数に実数(小数点がついてもよい数値)と整数(小数点がつかない数値)があることを説明しましたが、変数の場合も同じです。実数変数は更に単精度型と倍精度型の2つがあるので、下表のようになりますが、とりあえず
int(整数), float(単精度実数), char(文字)
の3つは最低覚えてください。
変数の型
型 | 型表記 | サイズ | 表現できる数値の範囲 |
文字 | char | 1バイト | -128~127 |
Short整数 | short | 2バイト | -32,768~32,767 |
整数 | int | 4バイト | -2,147,483,648~2,147,483,647 |
単精度実数 | float | 4バイト | 約7桁 +/-(3.4e-38~3.4e38) |
倍精度実数 | double | 8バイト | 約16桁 +/-(1.7e-308~1.7e308) |
次に、上記のプログラムには、変数に数値を代入する
a=1.0;
のような実行文が出てきました。これは、代入文といって、右辺の数値定数や変数(または、それらを組み合わせた数式)を、左辺の変数に代入する操作をコンピュータに指示します。左辺は必ず変数でなければいけないことに注意してください。
3.14=PI; /* これは間違い*/
のように書くことは誤りです。また、右辺は数値定数だけでなく、変数、または それらを組み合わせた任意の数式を書くこともできます。例えば、
a=1.0+2.0+5.0 や a=5.0*(1.0+b)+c
など。
以上の説明を念頭において、実際のプログラムをみてみます。
例 2-1/* 変数を使ったプログラム */ #include <stdio.h> int main(void) { float a,b,sum; a=1.0; b=2.0; sum=a+b; printf("sum=%e\n",sum); return(0); } |
上記のプログラムで、まだ説明していない
float a,b,sum;という文がでてきました。C言語では、変数を使う前にその変数が何型の変数なのかを予め宣言しておく必要があるためです。 上記の例では、float型(単精度実数型)の3つの変数、a,b,sumを使うことを宣言しています。 3つの変数の宣言は、上記のように","で区切って1行で済ますこともできますが、3行に渡って
float a;
float b;
float sum;
と書いても良いです。ただし、宣言文の位置は関数 main の始まりの { の直後に書かなければいけません。
演習問題 2-1 (Revised : 2015/04/23) 円錐(底面の半径r[m]、母線の長さh[m])の表面積S [m2](=πr(r+h))を求めるプログラムを作り、(r, h)={(1.0, 1.0)、(0.1, 10.0)} の場合について計算をしなさい。また、πを3.141592653589793とする手計算の結果(電卓は使わないように)とコンピュータによる結果を比較して、何処の桁まで一致しているかを示し、その理由について考察しなさい。 [補足]: printfの書式指定を%eとすると7桁までしか表示されません。有効桁数を確認するためには、もっと長い桁数で表示する必要があります。例えば、%23.15e として、全体を23桁小数点以下の桁数を15桁の指数形式で表示してみてください。 |
キーボード入力(scanf関数) |
いままで、printf()関数を使うと、文字列や数値を画面に表示することができました。これに対して、 scanf()関数は、キーボードから打ち込んだ文字や数値を、コンピュータ内の変数に代入するために用います。 ちょうど、printf()関数の逆の働きをします。例えば、
scanf("%e",&a)
とすると、実数型変数 aに%e形式で、キーボードからの数値を入力します。scanf()関数の使い方の約束は、printf()関数の場合とおおよそ同じと考えることができます。ただし、変数aの前に&記号がつくなど、全く同じではない点に注意してください(この理由はこの授業のずっと後の方で説明します)。
キーボードから数値を入力するプログラムを練習するために、以下の例題をやってみてください。
例 2-2(Revised : 2011/04/21)/* キーボードから数値を入力するプログラム */ #include<stdio.h> int main(void) { float a; printf("Input a= "); fflush(0); scanf("%e",&a); printf("a=%e\n",a); return(0); } |
例2-2ができたら、今まで出てきた例題の応用問題として、 キーボードから2つの数を入力し、その足し算結果を画面に表示する次の例題をやってください。
例 2-3 (Revised : 2011/04/21) /* キーボードから入力した数の足し算とその画面表示*/ #include<stdio.h> int main(void) { int a,b,c,d; printf("Input a= "); fflush(0);scanf("%d",&a); printf("Input b= "); fflush(0);scanf("%d",&b); c=a+b; d=a-b; printf("%d + %d = %d\n",a,b,c); printf("%d - %d = %d\n",a,b,d); return(0); } |
各々の行でやっていることを具体的に説明すると、以下のようになります。
今まで出てきたところを、以下にまとめておきます。
◎printf()関数
printf()は書式出力の関数である。
printf("a=%d b=%d\n",a,b);
の例で示すように、printf(”書式”,出力変数)の形をしていて、基本的には、””で囲まれた文字列がそのまま出力される。ただし、\n 記号のように\マークが付いた文字はエスケープ文字と呼ばれ、画面制御を行う特別な記号として扱われる(\n:復帰改行)。そのため、画面上には表示されない。また、%(その後に続く文字を含めて)は、””の後に表記されている変数(上の例では、変数a,b)の値を、画面に表示する際の以下の約束の書式を表している。
エスケープ文字の例: \n : 復帰改行、 \t : 水平タブ、 \v : 垂直タブ、 \b : 1文字後退
%d: 整数(int型データ)の符号付き10進数表示
%f: 単精度実数(float型データ)の指数なし表示
%e: 単精度実数(float型データ)の指数つき表示
%hd: 2バイト整数(short型データ)の表示
%lf: 倍精度実数(double型データ)の指数なし表示
%le: 倍精度実数(double型データ)の指数つき表示
%f, %e は、printf関数では単精度実数型(float)と倍精度実数型(double)の両方に使える 。
一方、この後で説明するscanf関数では、単精度実数型(float)の場合は、%f, %e、倍精度実数型(double)場合は %lf,%le を使う必要がある。
%c : 文字型データの1文字
%s : 文字列データ
注1)変数と書式の型を合わせる。
必ず、表示する変数と同じ型の書式を指定する。例えば、変数aがint型の場合は、%dを指定する。間違えて、%fや%eを指定するとデタラメな値が表示されてしまう(エラーメッセージも出ないので注意する)。
注2)%や\の画面表示
上記のように、%や\は、printf文の中で書式やエスケープ文字を表す特別な目的で使われます。このため、そのままでは%や\の文字を画面表示することができません。文字として表示したい場合は、%% や \\ のように2回重ねて表記します。この様子を理解するために、次のようなprintf文を実行してみてください。
printf("%%\\\n%%%%\\\n");
キーボードからの入力データを、第一引数 ”‥”に記した%何とかの書式にしたがって、第二引数に記した変数(以下の例では、変数a)に代入する(変数aの先頭に&がつくことに注意する。理屈はしばらくわからなくてよい) 。ここで、%何とかの約束はprintf()の場合と同様である。
例:
scanf("%d", &a)
変数はプログラムの中で値を変えることができるデータであるのに対して、定数は値が固定されているデータです。定数は、変数と同様の型をもっており、以下のように数値や文字を直接的に表現します。
定数の種類
文字........'z'
文字列......"abcde"
整数定数........120
実数定数........2.3e2
C言語では、通常の数式と類似した約束で数式を表すことができます。そのための算術演算子に以下のものがあります。
算術演算子の種類
* 乗算 a*b aにbを掛ける
/ 除算 a/b aをbで割る
+ 加算 a+b aにbを足す
- 減算 a-b aからbを引く
% 剰余 a%b aをbで割った余り (注:a,bは整数型の数、実数型の数を使うとエラーになる)
変数名に使える文字は、半角の英字(a-z,A-Z)、アンダーバー( _ )、数字(0-9)、に限られます。πやθなどの全角文字を間違って使ってしまう人がいますが、使えないので注意してください。変数名は、上記の半角英数字とアンダーバ_ を組み合わせた名前とします。ただし、先頭は必ず英字でなければいけません。 小文字と大文字は区別されます。名前の長さは、一般的に最初の31文字までは有効です。さらに、 以下の予約語を変数名にすることはできません。
予約語
auto break case char const continue default do double else enum extern
float for goto if int long register return short signed sizeof static struct
switch typedef uinion unsigned void volatile while
a=b+c; c=1.3; のような
変数 = 式;
の形の実行文は、右辺の式を計算した結果を左辺の変数に代入するというコンピュータ処理をあらわしています。通常の数式のように、単純に左辺と右辺が等しいということを表しているのではないことに注意してください。
演習問題 2-2 (Revised : 2015/04/23) 例2-3を参考にして、キーボードから読み込んだ2つの数n,m(いずれもint型)の、積、商、及び2のべき乗(2n)を計算してint型の変数に代入するプログラム を作りなさい。ここで、べき乗は math.hをインクルードして算術関数pow(2.0,(float)n)を使うこと。 (補足:nの前の(float)はfloat型への型変換を明示的に行うキャスト演算子) 1.零でない数を零で割り算するとどうなりますか? 実際に計算を実行し、エラーの内容についても具体的に調べて答えなさい。 2.小数点以下の端数が出る割り算を行い、端数の扱われ方について具体的に調べ、その理由について説明しなさい。 3.べき乗演算(2n)により正しく計算できる整数型変数の最大数を調べなさい。つまり、(2n)をnを変えて計算し、正しい答えが表示される最も大きなnを求めなさい。また、考察では、求めた最大数とnの値を示し、なぜ扱える数に限界があるか、その理由について述べなさい。 4.2のプログラムの全ての変数の型をfloat型にすると、整数の時と比べて端数の扱われ方にどのような違いが生まれますか? 実際の計算結果を示し、考察すること。(補足:書式指定は、%fを使うことに注意) |