[前へ]   [目次へ]   [次へ]

++と--演算子(C/C++)

今回は、 ++ と -- 演算子についてです。
これまでにも数回登場していますが、
これらの演算子は少し特殊なものなので、その辺について書こうと思います。

++ 演算子は「インクリメント演算子」
-- 演算子は「デクリメント演算子」
と呼び、どちらにも「前置」「後置」の区別があり、
それを含めて「前置インクリメント」や「後置インクリメント」などのように呼びます。

「前置」「後置」の区別はその名の通り、
対象より前に置く「前置」、対象より後に置く「後置」として区別されます。
具体的には以下のようになります。

int main(void){
   
int n=0;
   ++n;
//前置インクリメント
   
n++;//後置インクリメント
   --n;//前置デクリメント
   
n--;//後置デクリメント
   
return 0;
前置、後置共に ++ は「対象に1加算」、 -- は「対象に1減算」を行います。
これは毎回値を出力してみれば分かります。
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
#include <stdio.h>

int main(void){
   
int n=0;
   ++n;
//前置インクリメント
   
printf("%d\n",n);
   n++;
//後置インクリメント
   
printf("%d\n",n);
   --n;
//前置デクリメント
   
printf("%d\n",n);
   n--;
//後置デクリメント
   
printf("%d\n",n);
   
//終了待ち
   
getchar();
   
return 0;
実行結果:
1
2
1
0


では前置、後置の違いは何なのでしょうか?
それは、演算時に返される値で、前置は「処理済みの値」が、後置は「処理前の値」が返される点です。
これは、 printf 関数の呼び出し中に演算を行えばわかります。
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
#include <stdio.h>

int main(void){
   
int n=0;
   printf(
"%d\n",++n);//(1)前置インクリメント
   
printf("%d\n",n++);//(2)後置インクリメント
   
printf("%d\n",--n);//(3)前置デクリメント
   
printf("%d\n",n--);//(4)後置デクリメント
   
printf("%d\n",n);//(5)
   //終了待ち
   
getchar();
   
return 0;
実行結果:
1
1
1
1
0

今回は、最初の4個が1になっています。
順番に見ていきましょう。

(1)5行目の開始時点で、 n は0です。
++n により n は1になり、前置なので処理後の1が返されます。

(2)6行目の開始時点で、 n は1です。
n++ により n は2になりますが、後置なので処理前の1が返されます。

(3)7行目の開始時点で、 n は2です。
--n により n は1になり、前置なので処理後の1が返されます。

(4)8行目の開始時点で、 n は1です。
n-- により n は0になりますが、後置なので処理前の1が返されます。

(5)9行目の時点では、 n は0なので、0が表示されます。


さて、ここで後置の演算子は「処理前の値を返す」という点で注意が必要です。
というのも後置の場合は式の一部に使った時、処理前の値を返すために一時変数を生成します。
(ただし、基本型かつ単体で使用した場合は基本的に前置後置の処理は同じになります)
実行速度が非常にシビアな場合は、後置の演算子のコストを考慮する必要があります。

C++クラス型の場合は一時変数の生成に int 型などの基本型と比べて数倍〜数十倍の時間が掛かる可能性があるため、
後置の演算子は生成に大して時間の掛からない基本型のみにしておいた方がいいでしょう。


さて、「インクリメント(increment)」と「デクリメント(decrement)」というのは、
プログラミングの世界では大抵「インクリメント=1加算」「デクリメント=1減算」という意味です。

何故これらの処理だけが特別な名前を与えられて専用の演算子があるかというと、
ループカウンタなどでこれらの処理は使用頻度が非常に高いためだと思われます。
for(i=0;i<10;i++) のようなループカウンタの続行式の定番は「1加算」ですし、
for(i=9;i;i--) という最大から最小へ向かうループでは「1減算」が定番です。

後者の減算していくループは継続判定の時に比較演算子を使わずに済むため、
わずかながら実行速度が上がる可能性があります。
しかし、0以外が条件のためi=0の時が実行されないなど面倒な部分はあります。

後者は読みにくいためどちらでもいい場合は前者がよく使われますが、
速度が必要な時には価値があることがあります。

[前へ]   [目次へ]   [次へ]

プログラミング講座 総合目次

最終更新 2008/10/17