R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

どちらを先にするのか?

最近知った、前置きインクリメントと後置きインクリメントの話です(ォィ)

++i と i++ は、どうやら挙動が違うらしいです。
僕はずっと、i++ しか使ったことがありませんし、本を読んで勉強する人では無いので(知識のシャストインタイム派とでも呼んでください)、こういう基本的な知識が抜け落ちていることは珍しくありません。

で、どうこういうより、かるあさんに教えていただいた、挙動が変わるサンプルで実行してみました(一部いじってます)


static void Main() {
  int i = 0;  PrintBack(++i);
  int j = 0;  PrintBack(j++);
}

static void PrintBack(int v) {
  System.Diagnostics.Debug.WriteLine(v.ToString());
}

結果は以下の通りでした。

1
0


つまり、++ を前に置くと先に 1 を加算し、++ を後ろに置くと後から 1 を加算していることがわかります。

で、これを踏まえて、0 ~ 9 までループを回して、画面に値を表示させて見ます。


static void Main() {
  int i = 0;
  while (i < 10) {
    PrintBack(++i);
  }
  System.Diagnostics.Debug.WriteLine("-------------------");
  int j = 0;
  while (j < 10) {
    PrintBack(j++);
  }
}
static void PrintBack(int i) {
  System.Diagnostics.Debug.WriteLine(i.ToString());
}

これは、前回の内容を単にループさせているだけなので、当然、次の結果になります。

1
2
3
4
5
6
7
8
9
10
-------------------
0
1
2
3
4
5
6
7
8
9


でも、

普通こんなことしませんよね?

こんな感じで書くことが多いんじゃないでしょうか?
(「for 使うぜ」、というツッコミは認めませんw)


  int i = 0;
  while (i < 10) {
    PrintBack(i);
    ++i;
  }


そして、この様に書いた場合は、当然、i++ と記述しても同じ結果になります。

そんな訳で、皆さんは、どちらを使用していますか?
そして、どのように使い分けていますか?

#単に、これが聞きたかっただけだったりする。

投稿日時 : 2006年12月18日 16:35

Feedback

# re: どちらを先にするのか? 2006/12/18 16:49 επιστημη

僕は明確に「あとからインクリ/デクリしたい」でない場合、
どっちゃでも構わん場合であれば前置インクリ/デクリです。

# 理由はあります。 ほんのちょっと速いのです。

# re: どちらを先にするのか? 2006/12/18 16:57 黒龍

いったん後置で書いたに気づいた範囲で前置に置き換えていきます。前置にする理由はえぴさん記載と同じですがいきなり書けない&ダウンカウントへの変更もすることが多々あるので。

# re: どちらを先にするのか? 2006/12/18 16:59 黒龍

使い分けに触れてませんでしたね^^;
使い分けは代入や判定などを同時に行う場合にどちらの値が欲しいかで使い分けてます。
j=i++;
j=++i;

# re: どちらを先にするのか? 2006/12/18 17:00

K&Rをよめ!!
あたしゃ耕地しか使いません。
一から耕すのが面倒だからです。
++i++ == ++j++
こんなネタなかったっけ?

# re: どちらを先にするのか? 2006/12/18 17:28 囚人

> επιστημη さん
> # 理由はあります。 ほんのちょっと速いのです

某所でも書いたけど、C++ な人はコレが癖になってますね。

てか、前置と後置で処理が変わるようなロジックは書かない方がいいですけどね。

# re: どちらを先にするのか? 2006/12/18 17:41 恣意の

> επιστημη さん
> # 理由はあります。 ほんのちょっと速いのです

そいや、ニ,三年前に以下を言う人がいたのを思い出した

「最近のコンパイラは優秀だから
    無駄な後置は前置に置き換えてくれる」

for文とかは置き換えてくれそうだけど
さすがにこの人のように全部を後置で書く勇気はなかった...

# どのみち、囚人さんの意見に賛成
# そして中さんの"++i++ == ++j++"で悩み中w

# re: どちらを先にするのか? 2006/12/18 17:53 とっちゃん

おいらは、後置派ですね。
といっても、++ をオーバーロードするようなクラス作ったことがないというのが本音ですw
#基本型で評価なしなら、どっちにおいても同じコードになると思いますよ<今のコンパイラ

その昔(2/10 のお話に出てくるような時代の話w)なら、どっちが速いは、議論の余地なく...だったこともあったけどw

前置が速くなるのは、評価が付いてくるときだけですから、その場合どちらを使うかは、コードの状況によりけりです。

中さんとは別のネタw
p[i++] = i;
or
*(p+i++) = i;
ってのもありませんでしたっけ?www

あとは、
*p++;
とかくか
p++;
とかww(こっちは古すぎかw)

# re: どちらを先にするのか? 2006/12/18 18:55 恣意の

># そして中さんの"++i++ == ++j++"で悩み中w

○| ̄|_

++をクラスに実装したテストコードを書いたら
そもそもコンパイルでエラーを吐かれると云う罠(知らんかった...

昔にネタになっていたってことは
エラーにされる前は鼻から悪魔だったのかしら?(表現が古いということでw

# re: どちらを先にするのか? 2006/12/18 18:57 かずくん

> επιστημη さん
> # 理由はあります。 ほんのちょっと速いのです

に対する補足。
Effective C++を読むと幸せになるかもしれません。

# re: どちらを先にするのか? 2006/12/18 19:09 かずくん

おっと、かきわすれてた。
あたしゃ、επι産と同じ派でげす。

理由は、Effective C++を読んだから。

# re: どちらを先にするのか? 2006/12/18 21:49 中博俊

ねたとしては
++i+++++j++
だったような。
さていくつみたいな。

# re: どちらを先にするのか? 2006/12/18 23:03 επιστημη

>> 僕は明確に「あとからインクリ/デクリしたい」でない場合、
>> どっちゃでも構わん場合であれば前置インクリ/デクリです。
>> # 理由はあります。 ほんのちょっと速いのです
>
> 某所でも書いたけど、C++ な人はコレが癖になってますね。

癖にならざるを得ないんですよね ^^;
C++では前置/後置の書き分けが必要で、しかも後置のばやい:

X X::operator++(int) {
X tmp = *this;
++*this;
return tmp;
}

みたいに書かなきゃならんわけで、当然ここにコピーが発生します。

片や前置なら

X& X::operator++() {
いっこ足す; return *this;
}

こりゃもー明らかに前置が早い。
ふつーのintなどではほとんど(まったく)差はない。
ならば通常は前置使っておくのが無難、と。

# re: どちらを先にするのか? 2006/12/18 23:58 刈歩 菜良

わたしもCを使っていたころはwhileやforの終了条件やifの条件式に直接インクリメント・デクリメント演算子を突っ込んだりしてましたが...

> てか、前置と後置で処理が変わるようなロジックは書かない方がいいですけどね。
そう!今はコードを工夫してパフォーマンスを上げる時代ではなく、可読性をより重要視する時代だと思います。
なので、C#の講習会でも前置と後置の違いについて教えませんし、たまにCやC++を知っている人から突っ込まれても「CやC++と同じです。しかし、前置/後置で処理が変わるようなコーディングは推奨されません。」といっちゃいます。

同様の理由で、複雑な演算式を書くときも、不要でも可読性を上げるためになるべくかっこを入れます(もちろん、わかりやすいように)。

# re: どちらを先にするのか? 2006/12/19 1:08 THREE-ONE

私は後ろですねー
正直前置を使ったことはありません

# re: どちらを先にするのか? 2006/12/19 6:59 ぽぴ王子

僕はC++はほとんどやってない人なので、実装にまで頭が回りませんでした。
見易さという点でやはり後置。
THREE-ONEさんと同じで前置は使ったことがなく。

> 今はコードを工夫してパフォーマンスを上げる時代ではなく、可読性をより重要視する時代

とりあえず重視すべきはココで。

if (foo) {
bar;
}

if (foo)
bar;
と書かれると違和感を感じるのと同じかもしれません。

あとは「処理が変わるようなロジックは書くな」というのもありで。
これは当然といえば当然の話ですが。

# re: どちらを先にするのか? 2006/12/19 14:00 R・田中一郎

こっ、こんなに反応があるとは・・・

-----------------------------------
πιστημη さん

>どっちゃでも構わん場合であれば前置インクリ/デクリです。
>
># 理由はあります。 ほんのちょっと速いのです。

囚人さんにも同じことを教わりました。
えぴさんも、C++ な人だから、やっぱり前置き派なんですね。


-----------------------------------
黒龍 さん

>使い分けに触れてませんでしたね^^;
>使い分けは代入や判定などを同時に行う場合にどちらの値が欲しいかで使い分けてます。
>j=i++;
>j=++i;

この書き方は、面白いですね。
僕も今度使ってみます。

-----------------------------------
中 さん

>K&Rをよめ!!

あれ、この本持ってましたよ。
なので、多分読んだんだろうな~、と言うことが判明しました。
ただ、大昔なので忘れちゃったのかも知れません。

>++i++ == ++j++

目が回りますが。

-----------------------------------
囚人 さん

>某所でも書いたけど、C++ な人はコレが癖になってますね。

ありがとうございました。
実は、囚人さんに聞いてから既に前置きで書くようになってたりします^^;

>てか、前置と後置で処理が変わるようなロジックは書かない方がいいですけどね。

そうですね。わかりにくいですもんね。

-----------------------------------
恣意の さん

>「最近のコンパイラは優秀だから
>    無駄な後置は前置に置き換えてくれる」

そうみたいですねぇ。
優秀だけど、前置きで書けるなら書いちゃっても良い気もします。

>for文とかは置き換えてくれそうだけど

実は、事の発端は、「for (int i = 0; i < 10; ++i) { } 」なんてサンプルコードを目にしたためだったりします。

-----------------------------------
とっちゃん

>といっても、++ をオーバーロードするようなクラス作ったことがないというのが本音ですw

僕もずっと書いてきて、欲しいと思ったことがありませんでした。
しかし「もしや僕の知らない有用な使い道があるかも知れない。」と思ってみたり・・

>中さんとは別のネタw
>p[i++] = i;
>or
>*(p+i++) = i;
>ってのもありませんでしたっけ?www

すみません。ついていけませんwww

-----------------------------------
かずくん さん

>Effective C++を読むと幸せになるかもしれません。

囚人さんからも教えていただきました。
この本に前置きの方が速くなる解説が載っているんですよね。
こんな話題を振った手前、買って読まねばなりませぬな^^;

>理由は、Effective C++を読んだから。

そんな書き方、気になるじゃないですかw
やっぱり買って読まねばなりませんな^^;

-----------------------------------
中博俊 さん

>++i+++++j++
>だったような。
>さていくつみたいな。

すもももももももも、みたいになっちゃてますが^^;

-----------------------------------
επιστημη さん

>癖にならざるを得ないんですよね ^^;

こっ、これはわかり易いっ!
そりゃあ、前置きにしますよね。

-----------------------------------
刈歩 菜良 さん

>> てか、前置と後置で処理が変わるようなロジックは書かない方がいいですけどね。
>そう!今はコードを工夫してパフォーマンスを上げる時代ではなく、可読性をより重要視する時代だと思います。

賛成ですっ。

>同様の理由で、複雑な演算式を書くときも、不要でも可読性を上げるためになるべくかっこを入れます(もちろん、わかりやすいように)。

これは僕も良くやりますね。
あまり多くなるなら、わざと一旦変数に突っ込んだり。


-----------------------------------
THREE-ONE さん

>正直前置を使ったことはありません

僕もです。
あんまり使う局面はなかったですし。
でも、使うとしたら刈歩さんの仰っていた以下のパターンは、ちょっと面白いなぁ、と思いました。

while (++i < 10) {
}

まあ、

while (i < 10) {
i++;
}

と書いた方がわかりやすいですけどね。

-----------------------------------
ぽぴ王子 さん

>僕はC++はほとんどやってない人なので、実装にまで頭が回りませんでした。

僕もですね。学んで、ちょっとしたものが書けるようになったので、もういいやっって感じでした。
で、もう忘れちゃってますw

>とりあえず重視すべきはココで。
>
>if (foo) {
>bar;
>}
>を
>if (foo)
>bar;
>と書かれると違和感を感じるのと同じかもしれません。

そうですね。僕も {} は必ず付ける様にしています。

if (foo) bar; だとわかりにくい。
(けど、人の perl ソースは、こういうの多い。スクリプト言語だからか・・・)

# cLggDDupiftHKC 2011/12/27 19:49 http://www.tat2x.com/

Stupid article..!

# mhkwgOLiBX 2011/12/29 21:11 http://www.healthinter.org/health/page/atripla.php

Unbelievable. Class..!

タイトル
名前
Url
コメント