• ベストアンサー

gccとvisualstudio

for(i=0;i<10;i++) a[i]=i; k=5; a[k++]=(k>5 || k++<6)? 10: 20; for(i=0;i<10;i++) printf("%d %d\n",i,); printf("%d\n",k); こういうプログラムを作成してgccでコンパイルして実行したとき, 0 0 1 1 2 2 3 3 4 4 5 10 6 6 7 7 8 8 9 9 7 という結果になったのですが、5 10という結果になったのが理解できません。どうしてこのような結果になったのでしょうか?またvisualstudioで実行した場合a[6]=10という結果になったのですがこれもどうしてでしょうか?ぜひ詳しく教えてくださいお願いします。

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

  • ベストアンサー
  • moritan2
  • ベストアンサー率25% (168/670)
回答No.2

a[k++]=(k>5 || k++<6)? 10: 20; この式が問題ですね。 この式の中にkが3個でてきますが、実行中にkの値が変化しています。 この式をどの場所から計算するかはコンパイラの自由なので3回出てきたkの値が5なのか6なのか7なのかコンパイラの都合で決まります。gccはおそらく左辺のk++を一番最初に実行し、その後右辺の計算時にはkは6になっていたと考えられます。 VisualStudioは右辺の計算を先にやったために右辺のa[k++]=の計算時にはkはすでに6になっていたと思われます。 このような書き方をすると期待通りの結果が得られる保障が無いので、してはいけない書き方とされています。

grapher
質問者

お礼

そういうことだったんですね!よく分かりました。ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

インクリメント, デクリメントや (複合) 代入演算子で変数の値を変えた場合, その変数の変更前の値は「新しい値を決めるため」にのみ使うことができます. この制約が守られていないプログラムがどのように動作するかは決められておらず, どのように動作しようとも (そして動作しなくても) よいとなっています. このことから, インクリメントやデクリメントについては「その変数は他の場所で現れてはならない」ということになります. 今のプログラムでは a[k++] = ... の文で, 左辺でインクリメントした k が右辺でも現れてしまっています. それがおかしな振舞いをしている本質的な問題です.

grapher
質問者

お礼

ありがとうございます。よく分かりました。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

> a[k++]=(k>5 || k++<6)? 10: 20; 一つの文の中で k を2回インクリメントしていることについての、 処理系による解釈の違いが出ているのだと思います。

grapher
質問者

お礼

解答ありがとうございます。がんばってみます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 最適化したプログラムによる計算時の問題(GCC)

    GCC(4.4.1)で曲線を数値積分して長さを求めるプログラムを作っています。 double totalLength; for(j = 1; j < d; j++) { ::: ここでdx,dyを計算 totalLength += sqrt(dx * dx + dy * dy); } printf("%f\n", totalLength); これをOptimize3でコンパイル、実行するとtotalLengthがデタラメで巨大な結果だったので、 以下のようにして細かく分析しようとしました。 for(j = 1; j < d; j++) { ::: ここでdx,dyを計算 totalLength += sqrt(dx * dx + dy * dy); printf("%f\n", totalLength); //for内に入れる。 } このようにすると、他の部分を操作していないにもかかわらず、期待通りのtotalLengthとなりました。 そこで for(j = 1; j < d; j++) { ::: ここでdx,dyを計算 totalLength += sqrt(dx * dx + dy * dy); printf(""); } とすると、やはり期待通りの結果となります。 sqrt関数はどちらの場合も正しい結果を返しているようです。 なぜprintfがないときは正しく加算されず、printfが存在する時は正しい結果となるのでしょうか。 また、Optimize1でコンパイルした場合はprintfしなくても正しい結果となります。 これはGCCのバグですか

  • (プログラムがあるため長文です)次の2つの違いは?

    C言語(VisualStudio.net2003)で組み合わせに関するプログラムを作成したのですが、(1)の式で、プログラムを実行させると、違う結果が出てしまい、(2)の式で実行させると、正しい結果が出ます。 (1)(コピーして、確認(実行)してみてください) #include <stdio.h> int main ( void ) { int n,r,k; int a=1; printf("n=?");scanf("%d",&n); printf("r=?");scanf("%d",&r); for ( k=1 ; k<=r ; k++){ a *= (n-k+1)/k; printf("a%d=%d\n",k,a); } return 0; } (2)a *= (n-k+1)/k; の部分を a = a*(n-k+1)/k; に変更する。 a *= (n-k+1)/k;という式が、a = a*(n-k+1)/k;ということを意味しているので、どちらでも正しい結果がでる気がするのですが、なぜ(1)では正しく結果が表示されないのでしょうか?教えてください。 また、(1)のような *= をつかってプログラムを組みたいとき、a *= (n-k+1)/k; をどのように変更すればよいのでしょうか?

  • Windows での gccの使い方

    パソコンの初心者です。プログラムを作った経験はあるのですが、Windowsでgccを使おうとして、思わぬところではまっています。http://www2.ktokai-u.ac.jp/~kfuji/cygwin/cygwin.htm より、cygwin をゲットし、起動することに成功しました。プロンプト「$」が現れ、昔作ったCプログラムは無事コンパイルされました。ところが、プログラム中にprintf("Hello \n"); 等のprintf文を書いてコンパイルし、$./a.exe を実行しても、標準出力にHello の文字が出力されないのです。おそらく簡単なところでつまづいているのだと思います。何を誤っているのでしょうか?助けてください。よろしくお願いします。

  • gccですが、コンパイルができません!

    以下のプログラムですが #include <stdio.h> int main() { Int col; char i; scanf( "%d", &col ); for( i = 0 ; i < 26 ; i++ ){ if( i > 0 && ( i % col ) == 0 ) printf( "\n" ); printf( "%c", 'a' + i ); } return 0; } 以上のプログラムをgccでコンパイルしました。 コンパイルするために入力した文字→  gcc p.c -o p.exe 以下のエラーがでてコンパイルできません。 p.c: In function `main': p.c:4: error: `Int' undeclared (first use in this function) p.c:4: error: (Each undeclared identifier is reported only once p.c:4: error: for each function it appears in.) p.c:4: error: syntax error before "col" p.c:7: error: `col' undeclared (first use in this function) p.c:17:2: warning: no newline at end of file  以上なぜコンパイルができないのですか? よろしくお願いいたします。

  • cygwinでのgcc

    畏れ入ります。 UNIXどタコですm(__)m 最近CYGWINで簡単にUNIXが体験できるということで早速インストールしました。 KDEとGNOME無事起動しました。 で、実は図書館で「Xlibで簡単プログラミング」というのを借りてきたので、ちょっと遊んでみようと思いとりあえずc言語がコンパイル、実行できるかどうかやってみたのですがうまくいきませんでした。 #include <stdio.h> int main(){ printf("HelloWorld \n"); } のようなプログラムをvimで作成するところまではうまくいきました。homeディレクトリに作成されていました。 それで gcc hello.c とやればよいのですよね?! 実は文字がたくさん出て、コンパイルできたのかどうか・・・?そして、a.outというファイルができるのですよね?間違っていますでしょうか? とりあえず、できていません・・・(>_<) ./a.out としても、no fileです・・・ なにか間違っていますでしょうか?

  • プログラムが上手く動作しません。

    質問です。 1.整数を1個入力し、その数を3で割った余りが0ならば"Good morning"、1ならば"Good evening"、2ならば"Good afternoon"と出力するプログラムを作成せよ。ただしswhitc文を用いること。 という問題で私は #include <stdio.h> main() {      int a;      printf("整数a:");      scanf("%d",&a);      switch(a%3)      {      case '0':           printf("Good morning \n");           break;      case '1':           printf("Good evening \n");           break;      case '2':           printf("Good afternoon \n");           break;      } } と考えましたが実行しても入力はできますがprintfが表示されません。 どこが間違っているのでしょうか?ちゃんとコンパイルはできるのですが・・・。 2.10個の整数値をキー入力し、合計と平均値を計算してその結果を表示するプログラムを書きなさい。 #include <stdio.h> main() {      int a[11],b,c,i;      for(i=1;i<11;i++)      {           printf("整数%d:\n",i);           scanf("%d",&a[i]);      }      for(i=1;i<11;i++)           b+=a[i];      c=b/10;      printf("合計値は%d",b);      printf("平均値は%d",c); } というプログラムを考えましたが、計算結果がめちゃくちゃになってしまいます。 これもどこを直したらいいべきでしょうか?

  • windowsのコンパイラーで正しく実行されたのに、gccのコンパイラーでエラーがでた

    windowsのコンパイラーで正しく実行されたのに、gccのコンパイラーでエラーがでたソースコードです。ファィル名test.c です。Linux(Red Hat9) gccです。windowsのコンパイラーはCPad for Borland C++Compilerです。 #include <stdio.h> void main() //intからvoidに変更した { int i, j; for (i=1; i<=9; i++){ printf("%2d ",i); //%2dで、iが2桁に表示 } printf("\n"); printf("***************************\n"); //この罫線もどきの書き方はダサいので工夫してください for (i = 1; i<=9; i++){ for (j = 1; j<= 9; j++) { printf("%2d ", i*j); if (j == 9) printf("\n"); //1行表示後改行 } } return; //voidにしたので0を取った! } これがLinux(RedHat9)gccでは以下のエラーが出ます。 (test.c: 関数 `main' 内: test.c:4: 警告: `main' の戻り値の型が `int' ではありません)  なぜ、同じソースコードでエラーが起こるのですか?  Linux gccでは、この場合`int' 以外の何が必要なのでしょうか? 以上よろしくお願いします。

  • cygwinのgccで正常にコンパイルできない。

    cygwinのgccで正常にコンパイルできない。 cygwinのvimで、以下のプログラムを書きました。 ------------------------------------------------------------- #include <stdio.h> int main(void) { int no; printf("Please input something:"); scanf("%d", &no); printf("It is %d that you input it:\n", no); return (0); } ------------------------------------------------------------- それからgccでコンパイルしました。 コマンドは以下の通りです。 $ gcc test.c すると以下のエラーが出ました。 test.c:10:9: warning: unknown escape sequence: '\033' このようにコンパイルできない状態です。 どのようにすると正常にコンパイルできるようになるでしょうか?

  • C言語 解釈の違い

    #include <stdio.h> main() { int k, a[10], i; for(i=0;i<10;i++) a[i]=i; k=5; a[k]=(k>5 || k++<6)? 10: 20; for(i=0;i<10;i++) printf("%d\n", a[i]); } このプログラムについてなんですが、 a[k]=(k>5 || k++<6)? 10: 20; 特に、この部分について教えてください。 K++<6 と ++k<6 では実行結果が 異なってきますよね。 どうしてなんでしょうか。 まず、?の使い方がよく分かりません。 よろしくお願いします。

  • 行列をべき乗させるプログラム

    2行2列を5乗させるプログラムを作って、一応できたつもりだったんですが結果が合いません・・・ 何かヒントでもいいのでわかる方いらっしゃいましたらよろしくお願いします。 <プログラム> #include <stdio.h> #define N 2 int A[N][N]; int A_NEW[N][N]; int A_5[N][N]; /* 行列Aを5乗したもの */ int main() { int i,j,k,l; /* 2行2列の係数行列Aの成分を入力 */ printf("係数行列Aを%d行%d列で入力してください\n", N, N); for( i=0; i<N; i++) { for( j=0; j<N; j++) { printf("A[%d][%d]=", i+1, j+1); scanf("%d", &A[i][j]); } } for(i=0; i<N; i++) /* A_NEW=A*Aの計算 */ { for(j=0; j<N; j++) { for(k=0; k<N; k++) { A_NEW[i][j] += A[i][k] * A[k][j]; } } } for(l=0; l<3; l++) { for(i=0; i<N; i++) /* A_5の計算 */ { for(j=0; j<N; j++) { for(k=0; k<N; k++) { A_5[i][j] += A_NEW[i][k] * A[k][j]; } } } for(i=0; i<N; i++) { for(j=0; j<N; j++) { A_NEW[i][j] = A_5[i][j]; } } } printf("A_5=\n"); /* 出力 */ for( i=0; i<N; i++) { for( j=0; j<N; j++) { printf("%d ", A_5[i][j]); } printf("\n"); } } <入力例> A= 1 3 2 1 <期待する結果> A= 241 303 202 241 <このプログラムの結果> 406 498 332 406