前回の練習問題の解答例

#include <stdio.h>

int main(void)
{
	printf("選び方は%.0f通り\n",(43.0*42.0*41.0*40.0*39.0*38.0)/(6.0*5.0*4.0*3.0*2.0*1.0));
	return 0;
}
数式中の数値すべてに「.0」を付けて、実数にしている。 答は %.0f の場所に当てはめられて表示される。 %.0f のドットの後ろの数値は小数第何位まで表示するかを表しており、.0 は第0位までの表示、つまり小数点以下を表示しないという意味になる。

別解
または、最初の数値だけを実数にしてもよい。
#include <stdio.h>

int main(void)
{
	printf("選び方は%.0f通り\n",(43.0*42*41*40*39*38)/(6*5*4*3*2*1));
	return 0;
}
計算は左から順に行なわれるので、最初は 43.0*42 が計算される。 これには実数と整数が混在しているので、整数42 が実数42.0 に変換されて実数同士の演算となり、答は実数1806.0 となる。 すると、次の計算は 1806.0*41 となって、やはり実数と整数が混在しているので、整数41 が実数41.0 に変換されて実数同士の演算となる。 その後も同様に実数への変換が続き、最終的な答も実数となる。

変数

プログラミング言語における変数とは、1つの数値(あるいは文字)を一時的に記憶するためのメモリ領域に名前を付けたものである。 C言語で変数を使うには、初めに「宣言」(メモリ領域を確保し名前を付ける作業)をする必要がある。 宣言した後は、変数に数値を「代入」(つまり記憶)したり、代入されている数値を「参照」したりできる。 C言語の変数には、特定の種類の数値(あるいは文字)しか代入できない。 たとえば、整数しか代入できない変数、実数しか代入できない変数、という具合である。

覚えるべきこと
  1. 宣言(宣言文)
  2. 代入(代入文)
  3. 参照(記憶している数値を使う)


整数型変数

整数しか代入できない変数を「整数型変数」と呼ぶ。 税抜80円のバナナの税込価格を計算するプログラムで、整数型変数を使ってみよう。
#include <stdio.h>

int main(void)
{
	int sum;
		
	sum=80*108/100;
	printf("税抜80円のバナナの税込価格は%d円です。\n",sum);
	return 0;
}
「int sum;」は整数型変数の宣言文である。 メモリ上に整数1個分の領域を確保し、sumという名前を付けている。 「sum=80*108/100;」は代入文である。 右辺の式の答を左辺の変数に代入している。 そして、printfの中でsumに代入されている数値を参照している。
(注)代入文は「=」を使って書くが等式ではない。右辺の数値を左辺の変数に代入する文である。

変数の上書き

変数にすでに値が代入されている状態で別の値を代入すると、新しい値で上書きされ、古い値は消去される。 税抜80円のバナナの税込価格を計算した後で、税抜100円のバナナの税込価格を計算してみよう。
#include <stdio.h>

int main(void)
{
	int sum;
		
	sum=80*108/100;
	printf("税抜80円のバナナの税込価格は%d円です。\n",sum);
	sum=100*108/100;
	printf("税抜100円のバナナの税込価格は%d円です。\n",sum);
	return 0;
}
1つめの代入文でsumに86が代入されるが、2つめの代入文では108が代入される。 その時に、86は消去される。

変数を使った式

式の中で変数を参照することができる。 税抜80円のバナナを5本と、税抜600円のパイナップルを2個買った時の税込価格を計算してみよう。 式は (80*5+600*2)*108/100 だが、次のプログラムではバナナとパイナップルを別々の変数に代入している。
#include <stdio.h>

int main(void)
{
	int banana, pineapple;
		
	banana=80*5;
	pineapple=600*2;
	printf("税抜80円のバナナ5本と税抜600円のパイナップル2個を買うと、税込価格は%d円です。\n",(banana+pineapple)*108/100);
	return 0;
}
printfの中で、変数を含む式が使われている。

変数を参照した後で上書きする

先程と同じ問題(バナナ5本とパイナップル2個の税込価格)を、異なる方法で計算してみる。
#include <stdio.h>

int main(void)
{
	int sum;
		
	sum=80*5;
	sum=sum+600*2;
	sum=sum*108/100;
	printf("税抜80円のバナナ5本と税抜600円のパイナップル2個を買うと、税込価格は%d円です。\n",sum);
	return 0;
}
今回は、sumという名前の1つの変数しか使われていない。 代入文が3つあるが、注目すべきは2つめと3つめの代入文の右辺の式がsumを含んでいることである。 右辺が式になっている代入文では、まず右辺の式が計算され、その後で式の答が変数に代入されるという順番になる。 したがって、右辺の式を計算する段階ではsumは古い値であり、計算後に新しい値で上書きされることになる。 上の例では、1つめの代入文で400(バナナ5本の税抜価格)がsumに代入される。 2つめの代入文では、この400に1200(パイナップル2本の税抜価格)が加えられ、sumに代入される。 この時点でsumの値は1600である。 3つめの代入文では、1600に108を掛けて100で割り、税込価格が計算されて、sumに代入される。 最終的に、sumの値は1728となる。

代入演算子

先程のプログラムで、数式を含む代入文を次のように書き換えることができる。
#include <stdio.h>

int main(void)
{
	int sum;
		
	sum=80*5;
	sum+=600*2;
	sum*=108;
	sum/=100;
	printf("税抜80円のバナナ5本と税抜600円のパイナップル2個を買うと、税込価格は%d円です。\n",sum);
	return 0;
}
「+=」「*=」「/=」は、計算した後で代入する記号であり、代入演算子と呼ばれる。 「sum+=600*2」「sum*=108」「sum/=100」は、それぞれ「sum=sum+600*2」「sum=sum*108」「sum=sum/100」と同じ意味である。 ここで、「sum*=108/100」と書くことはできない点に注意。 こう書いてしまうと、まず右辺の108/100が計算され、次に掛け算が計算されることになり、計算の順序が変わってしまう。

5つの演算子に対応する5つの代入演算子がある。
代入演算子例の意味xが10だった場合の答
+=x+=3x=x+313
-=x-=3x=x-3 7
*=x*=3x=x*330
/=x/=3x=x/3 3
%=x%=3x=x%3 1


インクリメント演算子とデクリメント演算子

インクリメント演算子は変数の値に1を加えるもの、デクリメント演算子は変数の値から1を引くものである。
#include <stdio.h>

int main(void)
{
	int x;
		
	x=3;
	x++;
	printf("3の次の整数は%dである。\n",x);
		
	x=6;
	x--;
	printf("6の前の整数は%dである。\n",x);
	return 0;
}


インクリメント演算子とデクリメント演算子
演算子例の意味xが10だった場合の答
++x++x=x+1 あるいは x+=111
--x--x=x-1 あるいは x-=1 9


実数型変数

実数しか代入できない変数を「実数型変数」と呼ぶ。 4リットルの水を3人で分けるプログラムで、実数型変数を使ってみよう。
#include <stdio.h>

int main(void)
{
	double water;
		
	water=4.0/3.0;
	printf("4リットルの水を3人で分けると1人%fリットルになります。\n",water);
	return 0;
}
「double water;」は実数型変数の宣言文である。 メモリ上に実数1個分(正確には倍精度実数1個分)の領域を確保し、waterという名前を付けている。

定数

定数は、数値と対応づけられた文字列である。 文字列と数値の対応づけを定義すると、その文字列を数値として扱うことができる。 変数と似ているように見えるが、全く異なる。 変数では、メモリ上に値を代入するための領域が確保され、一度値を代入しても後から別の値で上書きすることができる。 それに対して、定数ではメモリ領域は確保されず、プログラム実行中に値を変更することはできない(もちろんプログラムを書きかえれば別の値に変更できる)。

覚えるべきこと
  1. 定義(定義文)
  2. 代入はできない


定数を使った式

税抜80円のバナナを5本と、税抜600円のパイナップルを2個買った時の税込価格を、定数を使った式で計算してみよう。 変数と定数を区別しやすくするために、定数は大文字、変数は小文字にするとよい。
#include <stdio.h>
#define BANANA_PRICE 80
#define PINEAPPLE_PRICE 600

int main(void)
{
	int banana, pineapple;
		
	banana=BANANA_PRICE*5;
	pineapple=PINEAPPLE_PRICE*2;
	printf("税抜%d円のバナナ5本と税抜%d円のパイナップル2個を買うと、税込価格は%d円です。\n",BANANA_PRICE,PINEAPPLE_PRICE,(banana+pineapple)*108/100);
	return 0;
}
「#define」で始まる文が定義文である。 半角スペースまたはTabで区切って文字列と数値を対応づけている。 これにより、プログラム中で定数の文字列が使われると、対応する数値に置き換えられて処理が進む (つまり、BANANA_PRICEは80に置き換えられ、PINEAPPLE_PRICEは600に置き換えられる)。

練習問題

温度T℃の空気中を、音は(331.5+0.61T)m/sの速さで進むという。 それに対し、光の進む速さはずっと早い。 そこで、雷が光ってから雷鳴が聞こえるまでの時間差を利用して、雷までの距離を計算したい。 光は一瞬で伝わるものとして、気温-1℃、雷鳴が聞こえるまでの時間12秒の場合の雷までの距離を求めるプログラムを作りなさい。 4つの実数型変数time, temperature, speed, distanceを宣言し、雷鳴が聞こえるまでの時間, 気温, 音速, 雷までの距離を順に代入していくとよい。