• ベストアンサー

インクリメント/デクリメント演算子を使った計算

Javaの質問に「インクリメント/デクリメント演算子を使った計算」というのがありました。 int a = 10; int b = a++ + ++a + --a - a--; 普通、こんなことはしないのですが、試しにやってみました。 これは int a = 10; int b = a++; b += ++a; b += --a; b -= a--; と同値だと思うのですが、手元の環境で次の結果となりました。   Java   bcc(C)   bcc(C++)  MinGW(g++) MinGW(gcc) (1) 11 : 10  11 : 10  11 : 10   11 : 10    11 : 10 (2) 12 : 22  12 : 22  12 : 22   12 : 22    12 : 22 (3) 11 : 33  11 : 30  11 : 30   11 : 32    11 : 32 (4) 10 : 22  10 : 20  10 : 20   10 : 22    10 : 22 ここで、各結果は「a : b」の形で (1) b = a++; (2) b = a++ + ++a; (3) b = a++ + ++a + --a; (4) b = a++ + ++a + --a - a--; を出力しています。 ただし、MinGW(gcc)のみoperation on `a' may be undefinedの警告が出ました。 どなたか、原因を教えていただけますか。 環境はWinXP Pro SP3, Java 1.6.0_14, bcc 5.5.1.2 gcc/g++ 3.4.5です。

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

Javaの場合、式中のオペランドの評価順序は厳密に規定されていますが、C/C++では不定になります。さらに、C/C++の場合、副作用完了点の前に同じオブジェクトを複数回更新した場合の動作は未定義ですので、どんな結果になるか分かりません。

nyan_wan
質問者

お礼

jacta様、回答ありがとうございます。 先ほど、asuncion様にお礼を書きましたが、jacta様の回答を見落としてしまい、大変申し訳ありません。 納得いたしました。ありがとうございます。

その他の回答 (1)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

>int b = a++ + ++a + --a - a--; bを求める途中で「どの時点の」aの値を使うかは、言語規格上、未定義です。 その結果、bがどういう値になるかは処理系の設計内容に依存します。 処理系によって一部異なる結果が出たのは、致し方ないことです。

nyan_wan
質問者

お礼

asuncion様、早速の回答ありがとうございます。 言語規格とはANSIのことと思いますが、昔K&Rには前置と後置の説明があったような記憶が・・・ (バイブルがどこに隠れたか分からない) 実務ではありえない話ですが、お付き合いいただきありがとうございます。

関連するQ&A

  • 前置き・後置きインクリメント。

    いつも大変お世話になり誠にありがとうございます。 標記の件。 参考書を見て、考えましたがピンときません。 どなたか解りやすく説明してもらいませんでしょうか? 2種類のコードと実行は下記の通りです. test1.c #include <stdio.h> int main(void) { int a = 0; int b = 0; b = a++; printf("代入後にインクリメントしたのでbの値は%dです。\n", b); return 0; } C:\MinGW>gcc test1.c -o test1 C:\MinGW>test1.exe 代入後にインクリメントしたのでbの値は0です。 test2.c #include <stdio.h> int main(void) { int a = 0; int b = 0; b = ++a; printf("代入前にインクリメントしたのでbの値は%dです。\n", b); return 0; } C:\MinGW>gcc test2.c -o test2 C:\MinGW>test2.exe 代入前にインクリメントしたのでbの値は1です。 前置き・後置きインクリメントの違いを論理的に ご説明願えませんでしょうか。 ご回答の程宜しくお願い申し上げます。

  • インクリメント/デクリメント演算子を使った計算

    Javaでのインクリメント演算子とデクリメント演算子を 使った計算についての質問です。 int a = 10; int b = a++ + ++a + --a - a--; このコード処理後の変数a,bの値の計算方法(考え方)が つかめず苦戦しています。 解答はa=10,b=22だそうです。 ちなみに例えば次のコードのb=a++;のように 右辺と左辺が1つずつの場合は理解しやすいです。 int a = 1; int b = 0; b = a++; //処理A 処理A後の変数a,bの値は b=aをした後でa=a+1を行うので a=2,b=1 となることは理解できます。 ご教授のほどよろしくお願いします。

  • インクリメント演算子

    はじめまして。プログラミングについて、とても初歩的な所で つまづいています。 変数を一つだけかつ、インクリメント演算子のみを用いて 整数値を一つ入力し,その整数値を1ずつ増やした結果を出す 4,5,6,7,8  (←このようにしたい) というプログラミングを書きたいのですが、どこのサイトを見ても 5個の文字の例はありませんでした。 2個までは以下の例でできました。 #include <stdio.h> main() { int a; printf("整数値を入力"); scanf("%d",&a); printf("1ずつ増加%d,%d,\n",a++,a); } もう、この問題で何日も立ち止まっています。 お願いです、どなたか助けてください。

  • 後置インクリメントの計算過程について

    後置インクリメントの計算過程について Javaに関して初めての質問となります。よろしくお願いいたします。数日前に学習し始めたばかりの超・初心者です。 現在、基本的な演算について、インクリメント・デクリメントのそれぞれ前置と後置の違いを学習したところなのですが、どうも後置の理解が完璧でないようで、仮に変数をxとした場合、式内にxが二度出てくる場合の後置の計算が理解できません。 具体的には int x, y; x = 10; y = x++ + x++; 上記でコンパイルした結果、y=21となる過程を教えていただけませんでしょうか。 私の理解では、x++は計算に使用した後にxに1を加算するので、まず y = 10 + 10 で、y = 20 となり、その後にxに1を加算してx=11が私の理解です。 よろしくお願いいたします。

    • ベストアンサー
    • Java
  • C言語でO-Notepad-x,文字化け。

    いつも大変お世話になりありがとうございます。 標記の件。 ボクはTeraPadをエディターに使っています。 コードとコンパイル、実行がおかしくなりました。 コードと実行は下記の通りです。 #include <stdio.h> int main(void) { int a = 0; int b = 0; b = a++; printf("代入後にインクリメントしたのでbの値は%dです。\n", b); return 0; } C:\MinGW>gcc test1.c -o test1 C:\MinGW>test1.c 実行するとO-Notepad-xと言うのが起ち上がって #include <stdio.h> int main(void) { int a = 0; int b = 0; b = a++; printf(" ɃC N g ̂ b ̒l %d ł B\n", b); return 0; } という結果になりました。 どうしてでしょうか? ご回答の程、宜しくお願い申し上げます。

  • bccは分かりましたがgccが使えません

    Cのソースの#include <stdio.h>でエラーになります。 gccではbccのbcc32.cfgで行うような設定はどのようにすればよいですか? MINGWのコンソールで $ echo $C_INCLUDE_PATH c:/msys/1.0/mingw/include;c:/msys/1.0/mingw/lib/gcc/mingw32/3.4.5/include このように出ます。 $ gcc myapp.c で#include <stdio.h>の行でコンパイルエラーです。 MINGWでは$C_INCLUDE_PATHを正しく設定できているみたいですが、gcc.exeにそれが伝わっていないみたいです。 AUTOEXEC.BATには何も追記したくないので何も追記していません。 どうすればライブラリのパスを通せますか?

  • インクリメント、デクリメントの順序について

    式中にインクリメント、デクリメントがある場合、制御の順番はちゃんと定義されていないようですが ・これは、一度コンパイルされてしまったら、もう動作はその時置き換えられた形で固定される。 ・同じコンパイラ、同じ環境で、同条件でコンパイルした場合は、まず間違いなく同じ結果が得られる。 ・ただし、その順序はコンパイラ毎に違う可能性がある。 という事で正しいですか?

  • 条件演算子でのインクリメントの使用

    マクロとして以下のような定義をします。 #define max(x,y)  ((x)>(y)?(x):(y)) この時ある本に以下のような記述がありました。 「マクロでは、max(x++,y)が、((x++)>(y)?(x++):(y))に展開されてインクリメントが2回行われるという副作用が発生します。ここに示す実現は、int型しか扱えないことが欠点とです」 とありましたが、以下のプログラム #include<stdio.h> #include"max.h"←maxマクロの定義 int main(void) { double x=1.1,y=2.0,max; max(x++,y): max=max(x,y); printf("x=%f y=%f\n",x,y); printf("max=%f\n",max); return 0; } をコンパイルすると x=2.100000 y=2.000000 max=2.100000 の結果がでます。これは 1.条件演算子ではインクリメントは1回しかおこなわれない。 2.条件演算子はdouble型でも実現できる ことになります。 この事は「インクリメントが2回行われるという副作用が発生します。ここに示す実現は、int型しか扱えないことが欠点です」という事に反する結果だとおもいますが、どこか間違いがあるのでしょうか。宜しくお願いします。環境としてはRed Hat でviを使っています。

  • ANSIエスケープシーケンスの色表示

    MinGWのgccで以下のC言語のプログラムをコンパイルしたところ、色が表示されませんでした。私の環境(Windows xp sp3で32bitCPU,MinGWは最新版のmingw-get-inst-20120426)では、無理でしょうか。何かgccのオプションで対応できればと思い、お尋ねします。 #include <stdio.h> int main() { puts("\x1b[0;1;33m黄色です"); puts("\x1b[0m"); return 0; } 結果は 黄色です  と表示されました。

  • ctime_r宣言が無いのに何故かコンパイルが通る

    MinGW 5.1.3 (Full Install) で以下のソースをコンパイルしたところ、ctime_rが何処にも宣言されていないのに何故かコンパイルが通りました。 /* a.c */ #include <time.h> int main() {  //(実行エラーにはなるはずだが、コンパイルは出来るはず)  ctime_r(NULL, NULL);  return 0; } $ gcc -v -c a.c Reading specs from C:/MyPrograms/MinGW/lib/gcc/mingw32/3.4.2/specs Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=c,c++,f77,ada,objc,java --disable-win32-registry --disable-shared --enable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-java-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchronization --enable-libstdcxx-debug Thread model: win32 gcc version 3.4.2 (mingw-special) cc1 -quiet -v -iprefix C:\MyPrograms\MinGW\bin\../lib/gcc/mingw32/3.4.2/ a.c -quiet -dumpbase a.c -auxbase a -version -o ./ccyAbaaa.s ignoring nonexistent directory "C:/MyPrograms/MinGW/bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/include" ignoring nonexistent directory "/mingw/include" ignoring nonexistent directory "/mingw/include" ignoring nonexistent directory "/mingw/lib/gcc/mingw32/3.4.2/include" ignoring nonexistent directory "/mingw/mingw32/include" ignoring nonexistent directory "/mingw/include" #include "..." search starts here: #include <...> search starts here: C:/MyPrograms/MinGW/bin/../lib/gcc/mingw32/3.4.2/../../../../include C:/MyPrograms/MinGW/bin/../lib/gcc/mingw32/3.4.2/include End of search list. GNU C version 3.4.2 (mingw-special) (mingw32) compiled by GNU C version 3.4.2 (mingw-special). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 as -o a.o ./ccyAbaaa.s ところがリンクはエラーになります。 $ gcc -v a.o (略) ld -Bdynamic C:/MyPrograms/MinGW/lib/crt2.o C:/MyPrograms/MinGW/lib/gcc/mingw32/3.4.2/crtbegin.o -LC:/MyPrograms/MinGW/lib/gcc/mingw32/3.4.2 -LC:/MyPrograms/MinGW/lib/gcc -LC:/MyPrograms/MinGW/mingw32/lib -LC:/MyPrograms/MinGW/lib a.o -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt C:/MyPrograms/MinGW/lib/gcc/mingw32/3.4.2/crtend.o a.o:a.c:(.text+0x3a): undefined reference to `ctime_r' なぜコンパイルはできるんだろうと思ったのですが、やはりインクルードパスにあるヘッダ群に ctime_r らしきものはやはり見当たりません。 $ find . -type f | xargs grep "ctime_r" $ find C:/MyPrograms/MinGW/include -type f | xargs grep "ctime_r" $ find C:/MyPrograms/MinGW/lib/gcc/mingw32/3.4.2/include -type f | xargs grep "ctime_r" $ なぜコンパイルが通っているのでしょうか? [補足] このテストを行う前に GnuWin32 の libgw32c(glibc互換ライブラリで、この中のtime.hはctime_rを含む) をインストールしてコンパイル&リンクを試みましたが、やはりリンクエラーが出ていました $ gcc -I/path/to/glibc a.c -lgw32c undefined reference to `ctime_r' 今回の質問のテストを行う前にlibgw32cライブラリはアンインストールしています。

専門家に質問してみよう