C/C++におけるPostfix incrementとPrefix incrementの質問です.僕は今まで現在の行のプロセスが始まる前に計算されるのが++aで現在の行のプロセスが終わってから計算されるのがa++だと思っていたのですが違うようです.例えば以下のコードを書いてみました.
bool print(int counter)
{
cout << counter << endl;
return true;
}
int main()
{
int counter = 0;
if(print(counter) && counter++ > 0 && print(counter)){
cout << counter << endl;
}
return 0;
}
この場合出力は
0
です.最初のprintに渡される0が出力されて,counter++ > 0の段階ではcounterは0として比較されるようです.この条件が偽なので2回めのprintは呼ばれないですし,ifの中身も呼ばれないです.
次にcounterの初期値を1にします.
bool print(int counter)
{
cout << counter << endl;
return true;
}
int main()
{
int counter =1;
if(print(counter) && counter++ > 0 && print(counter)){
cout << counter << endl;
}
return 0;
}
この場合の出力は
1
2
2
です.最初のprintに渡されるのは1で,counter++ > 0は1>0で真.2個めのprintには2が渡されて,ifの中身のcounterも2ということだと思います.この2つの実験を合わせると
counter++ > 0の処理の時はまだインクリメントされていないが,
counter++ > 0 && print(counter)の処理の時にはprint(counter)のcounterはインクリメント済みということになると思います.同じ行での処理なので僕の今までの理解では説明できません.C言語のオペレーターの処理順序で説明できるかと思ったのですがそうではなさそうです.http://www.difranco.net/compsci/C_Operator_Prece …
こういう処理がどういう順番で行われるかの細かい定義が知りたいです.今回の例だけでなくインクリメントの処理全体を理解したいです.リンクなどがあればそういったものでも構いません.このサイトでもインクリメントに関する質問はされていますが,今回の例は説明できない気がします(https://oshiete.goo.ne.jp/qa/4753046.html)(あるいは僕が理解できていないのでしょうか?)
解答お持ちしております.
No.3ベストアンサー
- 回答日時:
・前置インクリメントは、インクリメントされた値が使われる
x= ++a ;
を等価なプログラムにするなら
a=a+1 ;
a_temp = a;
x=a_temp;
または
a_temp = a+1;
x=a_temp;
a=a+1 ;
どちらになるかは、規格では決まっていない。
・後置インクリメントは、インクリメントされる前の値が使われる
x= a ++ ;
を等価なプログラムにするなら
a_temp = a;
x=a_temp;
a=a+1 ;
または
a_temp = a;
a=a+1 ;
x=a_temp;
どちらになるかは、規格では決まっていない。
・ && は、左から順番に評価される。
左が「偽」なら、右は評価されない。(このとき 値0 ( 偽) となる)
if( ex1 && ex2 ) { doSomething ; }
を等価なプログラムに変えるなら次のような感じ
if (ex1) {f=true;} else {f=false;}
if ( f ) {
if (ex2) {f=true;} else {f=false;}
}
if (f) { doSomething;}
・変数の値が変化するような「副作用」は「副作用完了点」までに完了することになっている。
https://oshiete.goo.ne.jp/qa/4132534.html
おそらく、あなたが「現在の行のプロセスが始まる前/終わってから」と言っているのは、この「副作用完了点」を誤解した(あるいは理解が不十分な)ものでしょう。
counter++ > 0 && print(counter)
は次のようになります。
・ && は 左から順番に評価されます
・ 先に評価される counter++ > 0 は、インクリメント前のcounterの値で > 0 の比較が行われます。
・ && は 副作用完了点 なので、右の print(counter)を評価する前に(左が偽の場合は評価せずに) counter=counter+1 は完了しています。
ありがとうございます.
言われた通り副作用(side effect), 副作用完了点(sequence point)について調べなおしてみました.完全に誤解していたようです.
関数呼び出し演算子の(),&&,||,?,コンマはsequence pointであることから,counterのインクリメントは&&より先に完了している,ということで説明ができるということになると思います.ありがとうございました.
No.2
- 回答日時:
> So in the statement y = x * z++; the current value of z is used to evaluate the expression
> (i.e., z++ evaluates to z)
> and z only incremented after all else is done.
ご質問の場合
print(counter) && counter++ > 0 && print(counter) の構造は
expression && expression && expressionとなるので
(counter++ > 0) は、
(counter > 0)を評価して、その後counterがインクリメントされる
となるのではないでしょうか。
ありがとうございます.確かにexpression(式)を使った説明でも順序は規定済みのようですね.
JIS X 3010-1993(ISO/IEC 9899/1990)
構文で示されているか(35)、又は(関数呼出し演算子()、&&、||、?:及びコンマ演算子に対して)後で規定する場合を除いて、部分式の評価順序及び副作用が生じる順序は未規定とする。
つまり&&で挟まれているとその前後で副作用が生じないことは規定済み.この説明も僕が求めていた答えなのですが,No.3さんの説明の方が分かりやすく今後の人の参考にもなるかと思うのでベストアンサーはNo.3さんに渡します.ありがとうございました.
No.1
- 回答日時:
>プロセスが始まる前に計算されるのが++aで現在の行のプロセスが終わってから計算されるのがa++だと思っていたのですが違うようです
「現在の行」の意味が不明ですが、
a=1のとき
a++ は 1
++a は 2
ですよ。
>同じ行での処理なので僕の今までの理解では説明できません.
どこが理解できないのでしょうか?
評価されるときのcounterの値を順番に見ていけば
if(print(counter) 0 1
&& counter++ > 0 0 1
&& print(counter)){ x 2
cout << counter << endl; x 2
になりませんか?
ありがとうございます.
現在の行は”;”で区切られるまでの表現の意でした.
今回は>は++よりも先に処理されていますが,&&は++の後に処理されていますよね.これがどこで定義されているかが知りたかったんです.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・【お題】絵本のタイトル
- ・【大喜利】世界最古のコンビニについて知ってる事を教えてください【投稿~10/10(木)】
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
pythonの*
-
【至急!!!】python言語で本を見...
-
16進の10進変換について
-
pythonの この問題が分かりませ...
-
pythonで演算子を変数に代入す...
-
awk の int()に関数について
-
c言語 16進数の2進数への変換
-
チェックボックスのCGIへの値の...
-
至急、[python初心者] listを使...
-
until文
-
変数の中は文字列か数値か調べ...
-
Adafruit LIS3DH 3軸加速度セン...
-
JSONで文字列が長い時
-
Application.ScreenUpdating = ...
-
ACCESS テキストボックスを隙...
-
formで特定のinputを送信しない...
-
セレクトメニューで2つの項目...
-
[python] 文字列を変数名として...
-
VB6で、長い時間かかる処理...
-
実行時エラー 3020の対策
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
16進の10進変換について
-
【至急!!!】python言語で本を見...
-
c言語 16進数の2進数への変換
-
関数「exists」と「defined」の...
-
int(input("○○"))の使い方
-
シェルスクリプトで、空白(ス...
-
switch文のエラーについて
-
UWSCのSELECT文の記述方法
-
pythonで演算子を変数に代入す...
-
pythonの*
-
pythonを使ったプログラミング...
-
pythonで改行を含めてfindする方法
-
変数の中は文字列か数値か調べ...
-
Pythonの np.indicesに関する質...
-
python3について。
-
シェルスクリプト+perl
-
PythonのJanomeを使って品詞の...
-
python print文のエラー
-
perでメールが送信出来ない場合...
-
数値かどうかの判定方法
おすすめ情報