【C言語】if文内の演算子の優先順位について

このQ&Aのポイント
  • C言語のif文内での演算子の優先順位について調査しました。
  • プログラムの出力結果と予想した結果が異なるため、演算子の優先順位や判定手順について疑問を抱いています。
  • どの点が間違っているか説明していただけますか?
回答を見る
  • ベストアンサー

【C言語】if文内の演算子の優先順位について

【C言語】if文内の演算子の優先順位について こんにちわ。初めて質問を投稿させて頂きます。 宜しくお願い致します。 【環境】 OS:Windows XP(SP3) コンパイラ:Visual C++ 6.0 CPU:AMD Athlon X2 4200+ 【質問】 私は下記のプログラムを実行しました --------------------------------- 【プログラム】 #include <stdio.h> int main( void ) { int i = 1; int j = 2; printf( "i = %d\n",i ); printf( "j = %d\n",j ); if( (i = 0) && (j = 200) == 200 ){ printf( "\n(1)-----------------------------\n" ); printf( "i = %d\n",i ); printf( "j = %d\n",j ); } printf( "\n(2)-----------------------------\n" ); printf( "i = %d\n",i ); printf( "j = %d\n",j ); return 0; } 【出力結果】 i = 1 j = 2 (2)----------------------------- i = 0 j = 2 //(※) --------------------------------- 私は【出力結果】(2)のj = 2という出力結果(上記(※)の行)は j = 200にならないとおかしいと思っております。 なぜなら、私は【プログラム】内のif文「if( (i = 0) && (j = 200) == 200 )」 の判定手順が下記の様になると考えているからです。  (1)i = 0を実行  (2)j = 200を実行  (3)(i = 0)の判定実行   →判定の結果「0」なので&&の右側の判定「(j = 200) == 200」    を行うまでも無くif文全体の判定がFALSE。 しかし、実際は「j = 200」が実行されてないので、上記(2)と(3)の 判定手順が逆転している様に見えます。 C言語の優先順位を見ると「&&」や「==」よりも「()」の方が高いと 記憶してるので、(2)→(3)の順に実行されないとおかしいと思ってます。 しかし、私の予想した結果と実際の出力結果が異なるので私の演算子の優先順位 やif文内での判定手順の理解に間違いがあると考えています。 出来ましたらどの点が間違っているのかご教授願えませんでしょうか? 宜しくお願い申し上げます。

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

  • ベストアンサー
回答No.5

if文内に記述された代入式が評価よりも先に実行されると考えている部分が間違いです。 実際の動作の流れは、 if (A&&B) の形なのでまずAを評価する必要がある Aは(i=0)なので、iに0を代入し0を評価する値とする 0は偽なので、Bは評価せずに終了する。 という形です。Bに書かれた(j=200)という代入式は、Bが評価された場合のみ実行されます。

murakou0925
質問者

お礼

・お礼に書くべき内容を補足に書いてしまいました。 大変失礼致しました。

murakou0925
質問者

補足

・お忙しい中、ご回答頂きありがとうございました! 私はC言語で「()」の演算子がついていればどんな条件下でも全て「()」の中から 絶対に実行されるんだと思い込んでいました。 if文(もしかしたら、if文以外の判定処理でも)の様な判定処理では「()」の 中から実行されるわけでなく判定処理から実行されるという事が理解できました。 ありがとうございました。

その他の回答 (6)

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

>#6さん >(1)iに0を代入しますよ >(2)jに200を代入しますよ >(3)i=0で、j=200なら下のプログラムを実行しますよ だから、違いますってば。 (1)iに0を代入する。 (2)i = 0という式を評価する。結果は0(C言語でいうところの偽)となる。 (3)&&以降を「評価しない」。 よって、jに200を代入することは「ありません」。

murakou0925
質問者

お礼

・お忙しい中、ご回答頂きありがとうございました! 私は、「()」演算子がどの様な条件下でも"必ず"「()」の中から 実行されるのだと思い込んでいました。その点が間違っている事 に気が付きました。 ありがとうございました。

  • sizu4444
  • ベストアンサー率0% (0/2)
回答No.6

すでに他の方が答えてるので私は言わなくてもいいのかもしれませんが・・・ if( (i = 0) && (j = 200) == 200 ) この部分ですが、 (i = 0) && (j = 200) == 200 という条件を満たすなら下のプログラムを実行せよ って命令ですよね? 手順としては (1)iに0を代入しますよ (2)jに200を代入しますよ (3)i=0で、j=200なら下のプログラムを実行しますよ という命令なので、もし命令を実行したいのであれば・・・ if( (i = 0) && (j = 200) == 200 )  この部分を i=0; j=200; if( i == 0 && j == 200 )  こういう風に変えればプログラムを実行できると思いますよ?

murakou0925
質問者

お礼

・お忙しい中、ご回答頂きありがとうございました! 私の書き方が悪く、私の質問の内容が上手く伝わらなかったかもしれません(>_<) ちょっと私が求めていた回答と異なりますが、参考にさせていただきます。 ありがとうございました。

回答No.4

こんにちは。 if( (i = 0) && (j = 200) == 200 ) という条件は ・変数 i に 0 を代入する ・結果 0 を返し、評価する ・0 なのでここで if 判定は「偽」とみなし、以下は実行されない が正解だと思いますが、最初から何もこのようにわかりにくいコードを書かないことです。 何がしたいのか、もっとストレートに表現できませんか? 代入文の結果を評価に使えることは C では禁止されていませんが、 自分でも判断がつかないような表現をわざわざしないことです。

murakou0925
質問者

お礼

・お礼に書くべき内容を補足に書いてしまいました。 大変失礼致しました。

murakou0925
質問者

補足

・お忙しい中、ご回答頂きありがとうございました! >最初から何もこのようにわかりにくいコードを書かないことです。 分かりました・・・。処理の内容を見直し、分かりやすいコードに 書き直してみます。

  • okormazd
  • ベストアンサー率50% (1224/2412)
回答No.3

>if( (i = 0) && (j = 200) == 200 ) ( )は優先されています。ただこの場合は,(i=0)を評価した後,&& 以下がどうであろうと,もはや真にはならないので,(j = 200) == 200 は評価されません。(i=0)のあとの演算で真になる可能性のある演算子,たとえば"+"とかだったら,たとえ結果として偽になるとしても,(j = 200)も評価されると思います。無駄にならないようなコンパイラの仕様だと思います。

murakou0925
質問者

お礼

・お礼に書くべき内容を補足に書いてしまいました。 大変失礼致しました。

murakou0925
質問者

補足

・お忙しい中、ご回答頂きありがとうございました! コンパイラの仕様ですか・・・。このような変なif文を記述するとコンパイラごとに 違った動きをする可能性があるかもしれないという事ですね・・・。 誰が見ても間違えないようなコードを書くように心がけます。

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.2

> if( (i = 0) && (j = 200) == 200 ) このif文の判定式内で、最初に考えなければならないは「&&」と「==」の優先順位です。 a> 「(i = 0) && (j = 200)」 == 「200」 b> 「(i = 0)」 && 「(j = 200) == 200」 のどちらになるかでは、== の方が優先順位が高いので、bと解釈されます。 この段階では、括弧の優先順位を考えるような出番はありません。 そして、まず 「(i = 0)」 の評価を行い、その値が0なので、「(j = 200) == 200」の評価を行うことなく、結果の0が確定します。

murakou0925
質問者

お礼

・お忙しい中、ご回答頂きありがとうございました! 私の間違いはどんな条件下でも"常に必ず"「()」演算子の内容から 実行されるもんだと思い込んでいました。そのためj = 200になる と解釈しておりました。 その間違いに気が付くことが出来ました。ありがとうございました。

noname#198951
noname#198951
回答No.1

if文の後は、実行されているのではなく「条件」なので、i=0 かつ j=200 という「条件」の時と言う処理なので、if文の解釈自体が間違って覚えていませんか?

murakou0925
質問者

お礼

・お礼に書くべき内容を補足に書いてしまいました。 大変失礼致しました。

murakou0925
質問者

補足

・お忙しい中、ご回答頂きありがとうございました! もしかしたら、私のif文の解釈が間違ってるんだとおもいます・・・。

関連するQ&A

  • c言語 パスカルの三角形

    c言語でパスカルの三角形を出力するプログラムを作りたいのですが、上手くいきません。 何を直せばいいのか教えてください。 #include <stdio.h> #define N 10 int main(void){ int i, j = 1, x, y; int d[N][N]; /* 三角形を作成 */ for (i = 1 ; i < N ; i++){ d[i][0] = 1; while (j <= i - 1){ d[i][j] = d[i-1][j-1] + d[i-1][j]; j ++; } } /* 三角形の表示 */ for (y = 0; y < N; y++) { for (x = 0; x < N-y; x++) printf(" "); for (x = 0; x < y; x++) printf("%3d ", d[x][y]); printf("\n"); } return 0; } 実行結果 -2147417616 2665208 1629976532 1627572249 1629101723 1 1629982744 2665256 2665548 3407923 1629345053 1627571017 0 3538997 1629739051 10 1629345053 2665368 3670071 2665384 1629739040 1627927140 2665244 1628040295 57 1628810863 1629476960 1628602749 2665560 2665304 1629345053 0 1629739040 1629740576 1628992224 2 4411498 1628040588 -2147417600 0 1629476960 1629740664 1629739040 1 267574 0

  • C言語の問題

    以下はC言語の問題です。お教えください。 1000以下の素数を求めるプログラム prog.c を作成せよ。各素数を整数4桁で出力し、15個の素数を出力した時点で改行処理 を行うこと。作成したプログラムを提出せよ。 です。 僕の考えでは、 #include <stdio.h> #include <math.h> main(){ int i; int j; int ix; int k; printf("正の整数を入力して下さい: "); scanf("%d",&i); ix=(int)(sqrt((double)i)); k=0; for(j=2;j<=ix;j++) { if(i%j==0) { k=1; } } if(k==0) { printf("%d は素数です\n",i); } else { printf("%d は素数ではありません\n",i); } となると思うのですが。どうやら違うようです。全然わからないので、正しい答えを教えてください。

  • C言語について

    次のような問題です。 問 自然数nを入力し、nを3で割って割り切れるかどうかを判定し結果を表示する。「割り切れる」、「1余る」、「「2余る」のいずれかが入るものとする。 このようなものをつくりました。 #include<stdio.h> int main(void) { int n; printf("自然数:"); scanf("%d",&n); if(n==0){ printf("割り切れる\n"); }else if(n==1){ printf("1余る\n"); }else{ printf("2余る"); } return(0); } これで合っているかよろしくお願いします。

  • C言語の問題を教えてください。初心者です。

    1000以下の整数を入力して、それ以下の素数を出力するプログラムをつくっています。 一応自分でやってみたのですが、どうもうまくできません。自分ではどこが間違っているのかさっぱりなので間違い箇所を指摘し、どうすれば良いのかを教えていただきたいです。ほかに効率的なやりかたがあったらあわせてお願いします。 初心者なので易しく説明していただけるとありがたいです。 <自分でやってみた> #include <stdio.h> int main(){ int i,j,N; int a[1000]; for (i=2; i<=1000; i++) { a[i]=1; } for (i=2; i<=1000; i++) { for (j=i++; j<=1000; j++) { if (a[j]=1 && j%i==0) { a[j]=0; } } } printf("2以上1000以下の整数を入力してください\n"); scanf("%d",&N); printf("%d以下の素数は\n",N); for (i=2; i<=N; i++) { if (a[i]=1) { printf("%d\n",i); } } } よろしくお願いしますm(_ _)m

  • C言語  九九表

    九九表を作ろうとしたのですが、うまくいきません、解説お願いします。 #include<stdio.h> main() { int i ; int j ; for( i=1 ; i<=10 ; i++){ for( j = 1 ; j<=10 ; j++) { printf("%4d\n") , i*j ; } printf("\n") ; } } 結果 10 -748408832 -748408832 -748408832 -748408832 -748408832 -748408832 -748408832 -748408832 -748408832     が10個続いてました・・・・

  • C言語のIF関数のアドバイスお願いします。

    #include <stdio.h> int main(){ int x,i,div=0; printf("x="); scanf("%d",&x); for(i=1;i<=x;i++){ if(x%i == 0){ div++; } } if(ここがわかりません) printf("%dは素数です\n",x); else printf("%dは素数でありません\n",x); return 0; }

  • C言語で困っています...

    入力した数値の列だけ○と×を縦に、段々になるように表示する (最後の行は×にならなければいけない)プログラムを作成しています。 (実行例) ○と×を表示します。何列?:10            ×           ○×          ×○×         ○×○×         ×○×○×       ○×○×○×      ×○×○×○×    ○×○×○×○× ×○×○×○×○× ○×○×○×○×○× 途中までプログラミングできたのですが、 偶数の数値を入れたときはきちんと最後の行は×になっても 奇数の数値を入力すると○が最後の行になってしまい、うまくいきません。 どこがだめなのでしょうか? どなたか教えてください。 /* 入力した数値の列だけ、○と×を縦に、   段々になるように表示する(最後の行は×になる) */ #include <stdio.h> int main(void) { int i, j, n; printf("○と×を表示します。何列?:"); scanf("%d", &n); for (i=0; i<n; i++){ for (j=0; j<n; j++){ if (j >= (n - 1) - i){ if (j % 2 == 0) printf("○"); else printf("×"); } else printf(" ");//全角スペース } printf("\n"); } return 0; }

  • 配列について(C言語)

    配列の要素において一番目の要素以外を0にするプログラムを以下のように作成したのですが(while文を*b != 0という条件で作りたい)、while文内のところが間違っているためだと思われるのですが、うまく実行されません(実行しても何も表示されない)。どのようにしたらいいのでしょうか。または、何かが抜けている、ほかの部分が間違っている等もあるためにうまく実行されないということなのでしょうか。 #include <stdio.h> int main(void) { int a[5] = {5, 78, 2, 9, 0}; int i, *b; b = &a[0]; while (*b != 0){ if(*!=a[0]) *ptr=0; else *ptr=a[0]; } for (i = 0; i < 5; i++){ printf("ptr値 =%d ptrアドレス =%p \n", *ptr, ptr); } printf("\n"); return (0); }

  • C言語 プログラミング 行列演算

    下記のプログラムのおかしい点と解決法を教えてください。 コンパイルは通りますがうまく動きません。。 #include<stdio.h> #define MAX 500 int main(void){ int matrA[MAX][MAX],matrB[MAX][MAX],matrC[MAX][MAX],l,m,n,i,j,k; printf("lとmを入力してください:"); scanf("%d",&l); scanf("%d",&m); printf("行列Aを入力してください"); for(i=0;i<l;i++){ printf(">"); for(j=0;l<m;j++){ scanf("%d",&matrA[i][j]); } printf("\n"); } printf("nを入力してください(m = %d):",m); scanf("%d",&n); printf("行列Bを入力してください"); for(i=0;i<m;i++){ printf(">"); for(j=0;j<n;j++){ scanf("%d",&matrB[i][j]); } printf("\n"); } printf("C=\n"); for(i=0;i<l;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ matrC[i][j]+=matrA[i][k]*matrB[k][j]; } printf("%d",matrC[i][j]); } printf("\n"); } }

  • C言語 素数判定

    1000以下の素数を求めるプログラム kadai7-2.c を作成せよ。各素数を整数4桁で出力し、15個の素数を出力した時点で改行処理 を行うこと。作成したプログラムを提出せよ。 という問題なのですが、以下のプログラムを実行しても動きませんでした。どこが違うのでしょうか。ご指摘お願いします。 #include<stdio.h> #include<math.h> main(){ int i,j,ix,k,h; for (i=2;i<=1000;i++){ ix=(int)(sqrt((double)i)); k=0; for(j=2;j<=ix;j++){ if(i%j==0){ k=1; } } if(k==0){ printf("%4d",i); h+=1 if(h=15){ printf("\n"); h=0; } }

専門家に質問してみよう