- ベストアンサー
なぜ、i++なのか?(ものすごくくだらない質問です)
C言語や、それに文法が似ている言語では、 for(i=0; i<10; i++)... のような例をよく見かけます。 ここで、何故か++iよりi++を使うほうを非常によく見かけるのですが、何故なんでしょうか? 単独で使う分にはどちらでも同じなので、実際はどうでもいいのですが。 個人的には、++iは副作用がまずあって、その副作用の結果を返すのに対し、i++は副作用があることは同じですが、「副作用を起こす前の値」を返す演算ということで、i++の方が少々不自然な感じがしますので、++iの方が好きなのですが。 もし、何か特別な理由があることを知ってらっしゃる方がいたらお願いいたします。
- みんなの回答 (12)
- 専門家の回答
質問者が選んだベストアンサー
その他の回答 (11)
- kiwa67
- ベストアンサー率22% (82/357)
回答No.12
- kiwa67
- ベストアンサー率22% (82/357)
回答No.11
- Tacosan
- ベストアンサー率23% (3656/15482)
回答No.10
- tadys
- ベストアンサー率40% (856/2135)
回答No.8
noname#88772
回答No.7
- BLK314
- ベストアンサー率55% (84/152)
回答No.6
- asuncion
- ベストアンサー率33% (2127/6290)
回答No.5
- ymmasayan
- ベストアンサー率30% (2593/8599)
回答No.4
- hidebun
- ベストアンサー率50% (92/181)
回答No.3
- Tacosan
- ベストアンサー率23% (3656/15482)
回答No.2
- 1
- 2
お礼
回答ありがとうございます。 まさか、こんな沢山回答をいただけるとは・・・。 教科書などの書籍の影響ですか。確かにそれも大きいですよね。 昔の教科書とか、確かめてみなければ・・・。 C言語でなくとも、言語の入門書の最初のサンプルが Hellow World になってたり(^^;。 C++言語という名前も、i++の書き方の方が多かったからかもしれませんし。 効率を考えすぎて読みにくいプログラムを作るよりは、CPUや最適化にまかせた方がいいかもしれませんね。 私の質問も、あくまで、前置と後置のどちらでもよい場合に、何故後置が多用されるのか?ということです。 ボイド式以外でも、できるだけ計算順序を勘定に入れなければいけないような記述は避けたほうがいいですよね。私も、インクリメントやデクリメントは式中でなく、出来る限り単独で使う方針です。これは、副作用のある関数を式中に使う場合も同様の注意が必要ですね。
補足
うわぁ! 何と、K&R「プログラミング言語C」がi++を使ってました。 何とか手に入れたのが古本の「第2版のANSI規格準拠版」なので、はっきりとはわかりませんが、初版でも多分同じなのではないかと思います。 この本によりますと、最初は++iを使ってますが、第2章8節で前置++、--と後置の意味の違いを明記した後は、何故か基本的にi++を使っています。まだ全部を熟読したわけではないのですが、取りあえずこの時点では、何故そうするかの説明は無いようです。 多分、合理的な理由はあるのでしょうが、それとは別に「K&Rでi++を使っているから、たぶんこれが正しいやり方なのだろう」と思って後置の方を使ったプログラマが沢山いたことは間違いないと思います(^^;;;;。 ここらへんが多分正しそうな気がします(^^; K&Rが何故後置を使ったのか?は別質問になりますので、どうしても分からなければ別質問をするとします。取りあえず、考えられることは。 ・K&Rの使っていたコンピュータがi++の方が都合が良かった。 ・while(*s++ = *t++); のようなトリッキーだが便利な機能がCで書けるので、後置を使うことにした(C言語を売り出すためには、Fortran、Cobol、Pascalなどの既存の言語との差別化が必要だった)。 ・後置を使うと for(i ~;i ~;i ~)... という形になって形が綺麗である。 あたりが考えられます。 あと、C++ では 演算子のオーバーロードができるために事情が違うわけです。C++ の場合は後置++の方がほとんどの場合効率が悪いので、後置を使う特別の理由がない限りは前置の方を使うのが正しい、わけです。 ところで、#6さんへの回答への補足に間違いがあったのですが、#6さんが突っ込んでくれないので、自分の間違いの指摘をここでさせていただきます(__)。 Javaではクラスのインスタンスを作るときはnewを使うので勘違いしてしまいました。C++ で後置++を定義するときは、newは使わずに局所変数に自分のコピーを作って、それをreturnするのが正式のやり方なんですね。従って、C++;と単独で使った場合には、returnした後に自動的にインスタンスは破棄されるのでメモリリークは発生しない、わけです。 そのかわり、 A=C++; というようなことをやると、まずCの中のauto変数に自分自身のコピーを作ってそれを返すが、auto変数のインスタンスは消えてしまうので、Aはあらためてクラスのインスタンスを作って生成しなければいけない。つまり、自分自身のコピーを作る、という操作が「2回」必要になるわけです。で、Aのインスタンスもいずれは破棄しなければいけないので、破棄も結局は「2回」やらなければいけないわけですね。確かにこれは効率が悪い(^^;;;;; まあ、私はC++の文法もよく知らないし、C++のプログラムを作ったことは1度もないので、この間違いはご容赦ください(__)。 javaでは、そもそも++の再定義ができないし、newはあってもdeleteはないので「悩む必要がない」わけです。 なるほど。「自由には責任が伴う」ので、javaでは「自由を制限することで、責任も減らす」ためにC++より厳しい規則になっていて、そのかわりC++より悩みを少なくしているわけです(^^; 大分、仕組みが分かってきました(^^)。 結局、質問したことは無駄ではなかったわけです。勉強になりましたから(^^)。 ということで、大体分かったので、何か見落としていることがあって、誰かが突っ込んでくれる可能性があるのでしばらく締め切りは待つことにします。しばらくたっても突っ込みがなければ質問を締め切らせていただきます。