• ベストアンサー

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

マクロとして以下のような定義をします。 #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を使っています。

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

  • ベストアンサー
  • chokiki
  • ベストアンサー率36% (9/25)
回答No.2

x++;はxを評価した後にxをインクリメントする事は知っていますね? x=1.1; y=2; の時、x++ > y は偽です。 max(x++,y); が呼び出された時点で、xは1.1、yは2なので、 maxマクロは ((x)>(y)?(x):(y)) ↓ (1.1++>2?(x++):(y)) となり、条件式が偽なので、yが返され、x++は1度しか呼ばれません。 結果、インクリメントは1回しか行われないのです。 x=2.1;y=2;として実行してみて下さい。インクリメントは2回行われるはずです。 >2.条件演算子はdouble型でも実現できる これについてはわかりません。 すみません。

その他の回答 (2)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

>>インクリメント演算子が double 型に対して X3010を調べてみました。 X3010 - 6.5.2.4 後置換増分演算子または、 後置換減分演算子のオぺランドは、 実数型またはポインタ方の修飾版、 または、非修飾版を持ち変更可能な 左辺値でなければならない。 とあるので、規格上では、 整数型でも実浮動小数点型でも使用可能のようです。 #ただ、現存しているコンパイラで規格に則ったコンパイラは #かなり稀な為、この限りではないのも現状だとも思います。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

インクリメント演算子が double 型に対して「正常に」動作するかはよくわかりません。規約にあたって下さい。 インクリメントの回数の問題は、この場合、(x++) > (y) が false になり、後の x++ が評価されていないだけだと思います。

関連するQ&A

  • インクリメント演算子について

    インクリメント演算子について プログラミング超初心者です。 大学のプログラミングの課題で インクリメント演算子を使って 数字をひとつずつ大きく(小さく)していくという課題が出ました 私が作ったプログラムは以下のとおりです #include <stdio.h> int main(void) { int x ; //変数宣言 printf("整数値を入力してください:"); scanf("%d",&x); printf("1ずつ増加\n"); printf("%d,",x++); printf("%d,",x++); printf("%d,",x++); printf("%d,",x++); printf("%d\n",x); printf("1ずつ減少\n"); printf("%d,",x--); printf("%d,",x--); printf("%d,",x--); printf("%d,",x--); printf("%d\n",x--); } ちなみに、整数値は10にしました。 結果は 1ずつ増加 10,11,12,13,14 1ずつ減少 14,13,12,11,10 と、望んでるものになったのですが、疑問があるので質問させていただきます。 xを変数にすると、x++はx+1になると思うのですが表示されたのは10、11、…と 10から表示されました。 しかも、増加していった最後のxはなぜ14になるのでしょうか? 課題は出来たのですが、頭が混乱しています… 詳しく解説をお願いします。

  • インクリメント演算子

    はじめまして。プログラミングについて、とても初歩的な所で つまづいています。 変数を一つだけかつ、インクリメント演算子のみを用いて 整数値を一つ入力し,その整数値を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); } もう、この問題で何日も立ち止まっています。 お願いです、どなたか助けてください。

  • C#のインクリメント演算子のオーバーロード(前置きと後置き)

    インクリメント演算子をオーバーロードして、後置きインクリメントの場合に戻り値が演算前の結果を返すようにする方法はありませんか? class Sample {  public int x;  public int y;  public Sample(int x, int y)  {   this.x = x;   this.y = y;  }  public override string ToString()  {   return base.ToString() + " - x = " + x + ", y = " + y;  }  public static Sample operator ++()  {   x++; y++;   return this;  } } class EntryPoint {  public static void Main()  {   Sample sample = new Sample(1, 2);   // 「Sample - x = 2, y = 3」で、期待通り   Console.WriteLine(++sample);   // 「Sample - x = 3, y = 4」で、期待したのはインクリメントされる前の値である「「Sample - x = 2, y = 3」   Console.WriteLine(sample++);  } }

  • if文を条件演算子に書き換えについて・・・

    /* 読み込んだ三つの整数値の最大値を求めて表示 */ #include <stdio.h> int main(void) { int n1, n2, n3, max; puts("三つの整数を入力してください。"); printf("整数1:"); scanf("%d", &n1); printf("整数2:"); scanf("%d", &n2); printf("整数3:"); scanf("%d", &n3); max = n1; if (n2 > max) max = n2; if (n3 > max) max = n3; printf("最大値は%dです。\n", max); return (0); } 上記のソースコードを、条件演算子を用いた形にするという問題なのですが、初心者で理解しずらいところもありどうやっても同じ結果を出すことが出来ないため質問させていただきました。 ご教授お願いしますm(_)m

  • インクリメント演算子の前後

    インクリメント演算子(++や--)について伺いたいのですが、 以下のような場合、変数の前と後ろで何か処理上違いはあるのでしょうか? //文字列の最後までポインタを進める while ( *p1 ) { ++p1; } printf("%d" , *p++); のように(文法が間違っていたらすいません)、 出力した後でインクリメントするといった使い方の違いは分かるのですが、インクリメント単独処理での前後の違いがあれば教えていただきたいです。

  • C言語の関数に関する質問ですが

    C言語の初心者です。よろしくお願いいたします。 授業でこのような演習が出ました。 演習:実数x を入力したときの最大値を求めるプログラムを作れ. 実数x を入力すると,x; -x; x2; xの絶対値の平方根 の中で一番大きい値を答える プログラムを作れ(ファイル名はmax.c とする). 表示は以下のようにする. Input x: -0.5 【Enter】 Answer is 0.707107. #include<stdio.h> #include<math.h> double max(double a, double b){ if( a > b) return a; else return b; } int main(void) { double x,y; printf(\"Input x: \"); scanf(\"%lf\",&x); y = max (x,-x); y = max (y,x*x); y = max (y,sqrt(fabs(x))); printf(\"Answer is %f.\\n\",y); } このように書けばうまく実行できますが、関数の中に関数を使えないでしょうか。うまく言えないですが、たとえば、以下のように書いてみましたが、うまく実行できません。どう直したらいいでしょうか、お忙しい中教えていただけたらうれしいです。 #include <stdio.h> #include <math.h> int max(double a,double b) { if (a<b) return b; else return a;} int main(void) { double x,result; printf(\"Input x:\"); scanf(\"%lf\",&x); result=max(max(x,-x),max(pow(x,2),sqrt(fabs(x)))); printf(\"%.2f\",result); return 0; } よろしくお願いいたします!!

  • C言語の演算について

    次のプログラムを実行したらどう出力されますか。 微妙な代入演算の違いが分からないので、教えていただけないでしょうか。 #include<stdio.h> void main (void) { int x = 5; int y = 8; int z = 3; int a,b,c,d,e,f; a = y == x + z; b = !x; c = x + y / z; d = x *=z - 1; e = --y / --z; f = y+++ % x++; printf("%d,%d,%d,%d,%d,%d\n",a,b,c,d,e,f); } できれば途中のトレースも書いていただけると助かります。 よろしくお願いします。

  • ビット演算について

    以下のプログラムを作成して、int型、char型、long型のAND演算・OR演算の結果の違いを見ました。 実行結果からchar型だけ結果の表示の仕方が他と異なっています。 一般的に、バイト数では、 char(1バイト) < short(2バイト) < int(4バイト) のはずなのに、出力結果は、 char(0xffffffff) > short(0xff) = int(0xff) となっていて、charが一番大きく?、shortとintが同じ結果? のようにみえてしまいよくわかりません。 私は、ビット演算が苦手なので、根本的に考え方が間違っているのかも しれませんが、どうしてこのような出力結果となるのか教えてください。 プログラム #include <stdio.h> #include <stdlib.h> int main() { int xi = 0x7F, yi=0x80; int stri1 = xi&yi; int stri2 = xi|yi; printf("** int **\n"); printf("%p\n",stri1); printf("%p\n\n",stri2); char xc = 0x7F, yc=0x80; char strc1 = xc&yc; char strc2 = xc|yc; printf("** char **\n"); printf("%p\n",strc1); printf("%p\n\n",strc2); short xl = 0x7F, yl=0x80; short strl1 = xl&yl; short strl2 = xl|yl; printf("** short **\n"); printf("%p\n",strl1); printf("%p\n\n",strl2); return(0); } 出力結果 ** int ** 0x0 0xff ** char ** 0x0 0xffffffff ** short ** 0x0 0xff

  • インクリメント演算子でのオブジェクト(変数)を評価する時期

    インクリメント演算子について以下のような例題を考えてみました。 #include<stdio.h> int main(void) { int at=0; if(at++) printf("True at=%d\n",at); else printf("False at=%d\n",at); return 0; } この時答えとしては Falsue at=1です。 これは、if文の制御式( )で at=0と判定しそのごat=1となるため、else文以降が実施されるためです。 atはメモリ上に配置されると思いますが、どの時点までat=0であり、どの時点でat=1になると考えたら良いのでしょうか。 アセンブリの問題になると思いますが、宜しく願います。

  • 論理演算について

    Cを勉強中の者です。論理演算についてよくわからいことがあります。 以下のソースコードを実行し結果が真なら0001、偽なら0000が出力されるプログラムを作りました。 #include <stdio.h> int main(void) { unsigned short a = 0x1234; unsigned short b = 0xfafc; unsigned short c = 0xcdef; unsigned short x, y; x = a && b; y = b && c; printf("x=%04x\n", x); printf("y=%04x\n", y); return 0; } 結果はx=0001, y=0001となります。y=0001はbとcの文字列がそれぞれfとcをを持っているので演算による結果は納得できますが、x=0001はaとbの文字列には共通するものがないのになぜx=0000ではないのでしょうか? また0xが頭に付く表現は16進数だと強調するためにあるのですか? 説明に不足があればまた足しますのでよろしくお願いします。

専門家に質問してみよう