算術演算

算術演算

やっぱり計算出来ないとプログラミングは始まりません。というわけでまずは算術演算。

int i = 0, delay_time;
//中略
i = i + 1;
double time = 8.5 - 2.1;
double cure = 1.5 * time;
double damage = cure / 10;
unsigned int temp1 = delay_time / 60;
tm_sec += delay_time % 60;
i += 1;
cure -= 10;
i++;
++i;
i--;
--i;

3行目から7行目が四則演算ですね。6行目の割り算は整数精度で行われ、小数点以下は0に近い方向に切り捨てられることを忘れないで下さい。

8行目は割り算の余りを求めるものです。これは整数精度の時のみ使えます。もし浮動小数点型で割り算のあまりを求めたいときは、math.hのfmod関数を使いましょう。

9行目は2行目の略記です。10行目のように引き算などほかの演算記号も同じように使えます。

11行目と12行目はインクリメント演算子、13行目と14行目はデクリメント演算子と呼ばれます。1増やしたり1減らしたりする処理を簡便に書くことができます。

演算演算子意味
インクリメント++a++a に 1 を加える(後置演算)
++aa に 1 を加える(前置演算)
デクリメント--a--a から 1 を引く(後置演算)
--aa から 1 を引く(前置演算)

使用上の注意です。下のコードを見てくだい。

インクリメント・デクリメント演算子は前置と後置で意味が変わるので注意です。私は覚えるのがめんdいので、後置しか使わない派です。

暗黙の型変換とキャスト

ここまでの例ではすべて計算するものの型は揃っていました。では違う場合はどうなるでしょう?

const int a = 10;
const double b = 3;
auto ans = a / b;
int ans2 = ans;
auto ans3 = (int)ans;

変数ansの型はdouble、ansには3.3333333(以下略)が入ります。

一方でans2の型はint、ans2には3が入ります。

また3行目のように型を明示することもできます。これを「キャスト」といいます。ans3の型はint型になります。

式の中で行われる変換
優先順位の高い型に変換されます。優先順位は
bool < char < short < int < long < long long < float < double
です。
代入時の変換
左辺の型と右辺の型が異なっている場合は、左辺の型に変換します。
キャスト時の変換
有無をいわさずに指定した型に変換されます。

この法則にしたがって解釈すると、3行目は、aの型はint、bの型はdoubleなのでaがdouble型に変換され(式の中で行われる変換)、double型同士の計算となります。
また4行目は変数ansの型はdoubleですが、左辺のans2の型がintなのでint型に変換されます(代入時の変換)。

このことを利用して割り算の余り(surplus)を求めてみましょう。

const double input = 23;
const int divisor = 7;
const int temp = (int)input / divisor;
const double surplus = input - (divisor * temp);

inputをキャストする必要があるのか?と怒られそうですが、べつに整数精度の結果で事足るのでキャストしました。

よくキャストを「ある型とみなす」と説明する人が居ますが、誤りです。bitの並びが変わることもあることからわかるように、実際に変換されます。

コーディングの作法

C言語のキャストは、非常に強力で、どんな型にでも変換ができます。ゆえにしてはいけない型変換もできてしまいます。
もっとも、まともなコーディングをしていればキャストを使う場面はほとんどないはずです。
もしあなたがキャストを使おうとしているならば、それはあなたが寝ぼけているのか、ライブラリ作者がうっかりしている、ということになります。
後者なら、作者に文句を言いましょう。(実際私はDxLibraryの作者に色の扱いについて文句を言って、Ver 3.13eで修正してもらいました)

signedとunsignedの変換はとくに理由のない限りしないようにしましょう。