標準入力(キーボード)からの数値の入力

 

これまでは、printf関数による文字列、数値の表示を行ってきました。
しかし、変数に代入された数値を表示させるだけでは、その変数の代入された値を変更しない限り、
実行結果は毎回同じになります。
変更する場合には、いちいちプログラムを変更しなければなりません。
そこで、その変更の作業をキーボードからの入力にしてしまえば、
プログラムを実行する際に自由に変更することが可能なので、非常に便利です。
つまり、キーボードからの入力により変数の値を決めてしまうわけです。
それには、scanf関数を用います。
正直言って、scanf関数はいろいろ問題があり、学校や企業等ではたいてい使いません。
しかし、scanf関数を使わない方法は今の段階では理解することが出来ないので(後の方で説明します)
仕方なくscanf関数を用います。
scanf
関数は

scanf("入力変換指定子",&変数);

と記述します。
入力変換指定子は出力指定変換子とほぼ同じです。ただし、double型の変数に代入する場合は%fではなく%lfと表記します。
これは、%fと記述した際にはfloat型と呼ばれるdouble型とは異なる実数を扱う型と解釈されます。
l
を付けることで、double型に変換させているのです。
あと注意が必要なのは、,のあとの代入する変数の前に&と付ける必要があります。
この&については後の方で説明しますので、今は取りあえず変数の前には&をつけなければならないと覚えておいてください。
次ぎのプログラムは、int型の変数adouble型の変数bとで四則演算を行わせるプログラムです。

#include <stdio.h>
int main(void){
        int a;
        double b;
        scanf("%d",&a);
        scanf("%lf",&b);
        printf("a+b=%f\na-b=%f\na*b=%f\na/b=%f\n"
                ,a+b,a-b,a*b,a/b);
        return 0;
}

上記のプログラムではscanf関数を2度使用していますが、以下のようにすれば1度だけで済みます。

scanf("%d%lf",&a,&b);

複数の変数にキーボードから代入するには

scanf("複数の入力変換指定子",複数の変数(すべてに&をつけ、,で区切る));

と記述します。複数の入力変換指定子は好きな文字で区切ることが出来ます。

scanf("%d,%d",&a,&b);

と記述した際は、23,56とキーボードから入力するとa23b56が代入されます。
scanf
関数はいろいろ問題があるといいました。
そのうちの大きな問題の1つとしてはオーバーフローと呼ばれるものがあります。
上記のプログラムにおいて、aに大きな値を代入してみてください。
すると、aには変な値が代入されて計算されていると思います。
これは、int型が扱える整数の範囲を超えてしまった場合に起きます。
int
型の範囲は以下のプログラムで表示させることが可能です。

#include <stdio.h>
#include <limits.h>
int main(void){
        printf("int: %d %d\n",INT_MIN,INT_MAX);
        return 0;
}

INI_MIMINT_MAXlimits.hで定義されているint型の扱える整数の最小値と最大値です。
私の環境では

int: -2147483648 2147483647

となりました。この値は環境により異なります。
もしもオーバーフローや数学的に定義できない場合等では例外が発生します。
例外が発生した際のプログラムの動作は処理系に依存します。
ここで、今までに紹介していない型、入力変換指定子、
出力変換指定子(どれも数値についてのみ)を紹介します。
まず型ですが、数値についての基本的な型はintdoubleで、
ここで書いたように、実数はdouble以外にfloatが存在しますが、
float
型はじつは全くといって良いほどメリットがありません。
まず実数を使用するならばdouble型を選んだほうがよいです。
なぜならば、今のコンピュータではdouble型のほうが、計算時間が短いし、
小数の精度もいいからです。よって、ここでは紹介のみにします。
次に、longについて紹介します。
long
は、intdoubleでは扱うことのできない桁数(小数も含む)をもつ値を扱うのに使用します。
このlongintdoubleの前に付けます。
ただしVisual Studioでは、long double型は普通のdoubleと同一であると定義されているようで、
あまり使用するメリットはありません。
次に、shortですが、こちらはlongとは逆で、
使用する値の桁数がintdoubleよりも小さいときにメモリ節約のために使用します。