• ベストアンサー

C言語 外部変数について

#include<stdio.h> int count; int f(int x){  int i;  for(i=0 ; x < 10 ; i++){   x*=2;   count++;   }  return x; } int main(void){  count=0;  printf("%d %d",f(1),count);  return 0; } のようなプログラムを作って実行してみたところ f(1)の部分は1024と自分の目的通りの結果が返ってきましたが countの部分が0とでてきてしましました 関数内で10回の繰り返しを行ったので 10がはいってると思ったのですが どこを直せば10の値がでてきますか?

noname#107977
noname#107977

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

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

> f(1)の部分は1024 本当ですか? >  for(i=0 ; x < 10 ; i++){ x < 10 のところが間違っていると思います。 > どこを直せば10の値がでてきますか? >  printf("%d %d",f(1),count); ここを、 printf("%d\n", f(1)); printf("%d\n", count); のようにしてみたらいかがでしょうか。 もとのコードでcountが10にならなかったのは、 おそらく、式の評価順が関係していると思います。

その他の回答 (5)

noname#62605
noname#62605
回答No.6

printfの式の評価順による影響です。これは処理系(コンパイラ)などの判断に依存する部分もありますので、なるべく依存しないようなつくりにしましょう。 (前略) int ret_sts = 0; … ret_sts = f(1); printf("%d %d",ret_sts,count); (後略) とすれば問題ないはずです。

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

i=0; f(i++, i++); は未定義動作になるからどんな処理になるかわからないはずです>#4. f(0, 1) かもしれませんし f(1, 0) かもしれませんし, あるいは f(0, 0) かもしれません. もちろん未定義なので (その他の結果も含めて) どうなっても文句はいえないんですが.

  • dummyplug
  • ベストアンサー率58% (134/230)
回答No.4

皆さんの回答にあるとおりなのですが、補足しておくと関数の引数の評価順序は(記憶によれば)不定だったはずです。 ですので、 i=0; f(i++, i++); みたいなコードを書くとf(0,1)になるかf(1,0)になるかはわからない(処理系の実装に依存)だったと思います。 質問のケースだと、countの値を評価するのとf(1)を評価する(関数呼び出しする)のとの順序はどうなるかわかりません。f(1)を呼び出した後にcountの値を取り出すとは限らない、ということです。 一般的にはC言語の引数渡しの規約に関連して、後ろの引数から順に評価することが多いです。多いですが、それを前提としてコードを書くと動かないケースが出ます。(例えば最適化すると動かなくなるとか。) これを避けるには、printf()の引数でf(1)を評価するのでなく、printf()の実行前にf(1)を呼ぶようにします。

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

関数呼び出しを実行する前に, 関数の引数 (と関数へのポインタ) は全て評価されます. そして, 関数の引数 (と関数へのポインタ) の評価順序は規定されていませんから, printf で表示される count の値は f(1) の実行前のものかもしれませんし実行後のものかもしれません. #1 のように変更すればいかなる処理系でも同じ結果になりますが, #2 にある「引数の順序」の変更ではまだ処理系に依存します (し, 変更しても結果が変わらない処理系があってもよい).

  • shred
  • ベストアンサー率35% (25/70)
回答No.2

printf("%d %d",f(1),count); を printf("%d %d",count,f(1)); に変更するか、もしくは f(1)を明示的に先に実行させた上で値をprintfに渡す。 関数呼び出し規約による問題です。

関連するQ&A

  • C言語のreturnの使い方

    return a, b; のように2つの引数で値を返せることを最近になり 知りました。ところで以下のような使い方は可能でしょうか? test( , )という2つの引数が必要な関数にnum()で return 1,2としてひとつの関数呼び出しで引数2個分に すると言うようなことです。 #include <stdio.h> int test( int i, int j){   printf("%d %d",i,j); } int num(void){   return 1,2; } int main(void){   test( num() ); }

  • C言語 勉強始めた所で、まだ良く解りません、教えてください!

    C言語 勉強始めた所で、まだ良く解りません、教えてください! このプログラムを実行すると、5,5と表示されると思うのですが? /*****************************************************************************/ #include <stdio.h> int average( int *data, int count ) { int i, sum=0; for( i=0; i<count; i++ ) sum+=data[i]; return sum/count; } int main(void) { int numbers [] = { 2, 3, 5, 7, 9, 11, 13, 15, 17,19 }; printf("%d\n",average(numbers,5)); return 0; } /*******************************************************************************/ 5、だけしか表示されません、これでよいのでしょうか?

  •  現在、私はC言語を学んでいます。

     現在、私はC言語を学んでいます。  プログラミングの初期の初期の問題なんですが、 「Hello World」という有名なプログラムがありますよね? それについての質問です。 #include<stdio.h> main() { printf("Hello World"); return 0; } も #include<stdio.h> main(void) { printf("Hello World"); return 0; } も #include<stdio.h> int main() { printf("Hello World"); } もちゃんと表示できます。 ここで質問です。 int main(void) int main() main() main(void) はどう違うんですか? あと、 return 0; はあっても無くてもいいようなんですが どういう意味があるんでしょうか?

  • C言語

    以下の出力結果はどうなりますか? 教えてください。 #include <stdio.h> #include <stdib.h> int main (void){ int n,f; n=792; f=2; while(f*f<=n){ while(n%f==0){ printf("%d",f); n=n/f; } f++; } if(n !=1) printf("%d",n); printf("\n"); return 0; }

  • C言語の質問です。

    #include"stdio.h" int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = a+b; printf("add=%d\n", add); return 0; } と、------------------------------------------------------------------------------ #include"stdio.h" int tasizan(int x, int y); int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = tasizan(a, b); printf("add=%d\n", add); return 0; } int tasizan(int x, int y){ int aa; aa = x + y; return aa; } の違いを教えてください。

  • 再帰について(C言語)

    今、再帰処理を勉強しています。 しかし、以下のプログラムがどうしても理解できません。 流れ的には一体どういう手順になっているのでしょうか? return i * fact( i - 1 )の部分を考えると頭が こんがらがってしまいます。 #include <stdio.h> int main( void ){  printf("5の階乗は %d です", fact(5) );  return 0; } int fact( int i ){  if( i == 1 ) return 1;  else return i * fact( i - 1 ); } --------実行結果---------- 5の階乗は 120 です

  • C言語

    #include <stdio.h> #include <stdib.h> int main (void){ double a[5]={0.0,4.0,0.0,-5.0,1.0}; double x; int i,j,k,n; n=4; x=0.75; for(i=1;i<=n;i++) printf("%10.5f ,",a[i]); printf("\n"); for (i=1; i<=n+1; i++) printf("----------") printf("\n"); while(n>=1){ for(i=1; i<=n; i++) a[i]=a[i-1]*x+a[i]; for(i=1; i<=n; i++) prontf("%10.5f ,"a[i]); printf("\n"); n=n-1; } return 0; }

  • C言語初心者です。

    C言語初心者です。 1^2-2^2+3^3-4^2…+99^2-100^2の値を求めるプログラムを作成したいのですが上手くいきません。 どこが足りないのですか? #include <stdio.h> int main(void) { printf("%d", 1^2 - 2^2 + 3^2 - 4^2 … + 99^2 - 100^2); return (0); } よろしくお願いします。

  • C言語の参照はずしについて

    ソートのプログラムなんですが #include <stdio.h> #include <stdlib.h> int comp(const void *, const void *); int main() { int i; int test[6] = {10, 8, 2, 6, 4, 0}; qsort(test, (size_t)6, sizeof(int), comp); printf("\n"); for (i = 0; i < 6; i++) printf("%d\n", test[i]); return 0; } int comp(const void *a, const void *b) { static int i = 1; printf("%02d--%d,%d\n", i, *(int *)a, *(int *)b); i++; return (*(int *)a - *(int *)b); } 最後のreturnの()の中身がよくわかりません。「参照はずし」という事をしてるらしいんですが「参照はずし」とは何ですか意味も教えてください。

  • C言語で困っています

    C言語で 100:1 99:2 98:3 .......ループ 1:100とやりたいんですが このやりかたがわかりません goto文などを使うのでしょうか? 一応コードは #include <stdio.h> int main(void) { int i,a; for(i=100; i>=1; i--){ for(a=1; a<=100; a++){ printf("%d:\n",i); break; printf("%d",a); } } return 0; } です まったくこれだと右側が出力されなくてだめみたいです どなたかお知恵をください お願いします

専門家に質問してみよう