質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

10回答

5153閲覧

後置インクリメントの1足されるタイミングについて

r--

総合スコア18

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2019/05/21 06:52

編集2019/05/21 20:53

■計算と同時に用いる場合

a=0;
b=a++;

先にbにaを代入して、その後aを増加させます。
aの値は1、bの値は0となります。???文章の意味のイメージができません。

後置きの場合は、他の計算の方が優先されることになります
後置の場合のみ
このタイミングについて教えてください

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/05/21 06:56

後置インクリメント 過去質問に結構出てきてるはずですし、 動作させて結果を得られたならそれが仕様なので「そういうもの」と飲み込むしかないですよ。
cateye

2019/05/21 07:01 編集

>このタイミング・・・機械語(javaの場合は中間言語)レベルのことを言っていますか?
guest

回答10

0

ここをイメージするにはどうしたらよいですか。

プログラミングはイメージで動くものではなく、確固とした規則に従って動くものです。「そういうルール」と割り切って使うほうがいいかもしれません。


なお、インクリメント・デクリメントを式の途中に組み込むと、どうしても見通しが悪くなります。わからないのであれば、「a++;」だけの式を作って、他の式の途中に混ぜ込むような書き方を使わないでいれば、悩む必要もなくなります。

投稿2019/05/21 07:05

maisumakun

総合スコア146581

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

解決済みですが・・・

本当は代入の後にインクリメントされると理解しないほうがよいと思います。

tacsheavenさん回答にもありますが、「後置インクリメントは式の評価が終わった後にインクリメントされる」という意味です。それを理解するには「式の評価ってどこ?」というのを正しく認識する必要があります。

java

1 b = a++ ; 2// <-> 式1: ここがインクリメント演算子の仕様に関係する式の範囲 3 4// 上記の動作をJavaで(ばらばらに分解して)表現するなら以下のように捉えるとよい 5 6 // 式1の評価開始 7 _1 = a ; // a++の式の結果はインクリメントする前の値 8 a += 1 ; // 次にaのインクリメントが起きる 9 // 式1の評価終わり。式1の結果は_1 10 b = _1 ; // 右辺の式全体の結果を左辺へ代入

こう理解しておくと、tacsheavenさんが挙げておられる2つ目の例がすんなり腑に落ちると思います。

java

1 b = a++ + a; 2// <-> 式1: ここがインクリメント演算子の仕様に関係する式の範囲 3// <-----> 式2: 右辺全体 4 5 // 式2の評価開始 6 // 式1の評価開始 7 _1 = a ; // a++の結果はインクリメントする前の値 8 a += 1 ; // 次にaのインクリメントが起きる 9 // 式1の評価終わり。式1の結果は_1 10 11 _2 = _1 + a; // 式1の結果とaを加算 12 // 式2の評価終わり。式2の結果は_2 13 b = _2 ; // 右辺の式全体の結果(式2の結果)を左辺へ代入

上記のような理解の仕方は言語の文法について少し厳密な理解が必要と思います。ひょっとするとここまで厳密に考えてコードを書く機会は少ないのかも知れません。

ここまで詳しく認識せずともmaisumakunさん回答の後半にあるように、確実に理解できている範囲内でコードを書けばよいと思います。似たような話で演算子の結合順位など結構あやふやにしか覚えていないことも多いんじゃないでしょうか?

自分についていえばa == 1 || b == 2ならどういう演算順位になるかはっきり認識しているので(a == 1) || (b == 2)を見ると「不必要な括弧をつけちゃってまぁ!」なぁーんて生意気なことを考えます。

しかしながら1 << i + 1なんて式になると<<+のどちらが先か不安になってきてついつい1 << (i + 1)のように括弧をつけたくなる衝動にかられます。実際にはこの括弧は不要なのでそもそも「不必要な括弧・・・」なんて生意気をいえるほど仕様を知っちゃいないわけです。

そんな自分は++をほぼ単独でしか使わないです。

array[j++] = j;なんてややこしい書き方はしません。おとなしく
array[j] = j; j++なりj++; array[j] = j;のように自分で確実にわかる書き方を好みます。


ただ、自分でコードを書くときにはいいのですが人のコードを見るときは正確な知識が必要です。++が使われたコードを見て「結果はどうなるんだろう」と思うようなら本回答の最初の方で述べたような仕様の知識が必要なこともあるかも知れません。

投稿2019/05/22 00:59

KSwordOfHaste

総合スコア18404

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

前置と後置の違いは、「式の評価が終わる前か後か」です。

++a; は、

  1. a の値を1増やし
  2. 式全体の値を評価して返す

という処理になっています。

では

Java

1a = 0; 2b = a++;

はというと、b = a++; の処理で、まず b = a; として処理が行われます。(なので b = 0)
その後、式の評価が終わったので、a の値を ++ で一増やすわけです。

これだともう少し分かりやすいですかね。

Java

1a = 0; 2b = a++ + a;

b = a++ + a は、まず a++ の部分が評価されます(評価値は a)。なので、
b = 0 + a となりますが、この時点で a++ の後置演算が動き、a の値が 1 に変化します。よってその次の

  • a の a の値は 1 と評価され、結果 b = 0 + 1 となります。

これが

Java

1a = 0; 2b = ++a + a;

だと、b の値は 2 になります。(最初の ++a の評価結果が 1 になるので、1+1 = 2です)

投稿2019/05/21 07:11

tacsheaven

総合スコア13707

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/05/21 07:18 編集

JavaやJavaScriptの場合は式が左から評価されることが保証されているので特に問題ないですが、C言語では同じ式で「a++」と「a」を併用すると、評価順が安定していないを通り越して意味不明な動作にもなりかねないので要注意です。 http://www.st.rim.or.jp/~phinloda/cqa/cqa7.html#Q8
tacsheaven

2019/05/21 07:21

ですね。そのことを明示しておくべきでした(というか、C でトラブったから他の言語では評価順を保証するようになったわけですが)
tacsheaven

2019/05/21 07:33

まあ、普通は私もああいうコードは書かない(混乱の元)ですが、知識としては知っとかないと困りますしねえ……(確かに C で食らった記憶はあるなあ……)
guest

0

java

1b = a++; 2 3```は 4```java 5b = a; // 先に「bにaを代入」し 6a = a + 1; // 次に「a+1」が実行される 7 8```という事であり 9```java 10b = ++a; 11 12```は 13```java 14a = a + 1; // 先に「a+1」が実行され 15b = a; // 次に「bにaを代入」が処理される 16 17```という事です。 18aの値が参照されてからaが+1されるのが後置の「a++」であり 19aが先に+1されてからその結果のaの値が参照されるのが前置の「++a」です。

投稿2019/05/21 07:19

HiroshiWatanabe

総合スコア2160

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

r--

2019/05/21 15:45

つまり、後置だと、b=0ということですね?
guest

0

Javaのドキュメントってこれでいいのかな。
英語もよく分かんないので間違ってたらすみません。


15.14.2. Postfix Increment Operator ++

The value of the postfix increment expression is the value of the variable before the new value is stored.

Google翻訳

後置増分式の値は、新しい値が格納される前の変数の値です。


15.15.1. Prefix Increment Operator ++

The value of the prefix increment expression is the value of the variable after the new value is stored.

Google翻訳

接頭辞増分式の値は、新しい値が格納された後の変数の値です。

投稿2019/05/21 07:07

fuzzball

総合スコア16733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

提示されたプログラムでは

a = 0; b = a++;

a = 0; b = a; a += 1;

こういう意味になるので、bにはインクリメント前の値が代入されます。

よってaは1、bは0という値になります。

投稿2019/05/21 07:07

dice142

総合スコア5158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ここをイメージするにはどうしたらよいですか

変数を参照するタイミングが前か後かの違いと思えばわかりやすいかも

投稿2019/05/21 07:02

flan

総合スコア146

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

前置の場合(++a)は、まずインクリメント(+1)してから処理を行い、
後置の場合(a++)は処理が済んでからインクリメントですね

投稿2019/05/21 06:55

編集2019/05/21 06:57
y_waiwai

総合スコア88163

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

javap で内部でどんなふうに代入と足し算がおこなわれいるかをしらべてみるとよいかもしれません。
javap -c とすると class ファイルの逆アセンブル(仮想マシン語の表示) ができます。

イメージ説明

iinc, iload, istore の順番に差があることが確認できます。

投稿2019/05/24 21:14

編集2019/05/27 11:20
katoy

総合スコア22328

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

r--

2019/05/26 03:32

これをするのに何が必要ですか?
katoy

2019/05/27 11:20

JDK を入れれば、 javap コマンドが使えるようになるはずです。
guest

0

解決済みですが。念の為。

複雑な式の中ではインクリメント/デクリメントを使わないというのも一つの手です。

少なくともC言語の場合、同一変数のインクリメント/デクリメントが式中に複数個あると動作未定義にすらなりえます。javaの場合は分かりませんけれど、多用するのは危険です。

投稿2019/05/23 14:49

HogeAnimalLover

総合スコア4853

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問