• ベストアンサー

関数の戻り値がこうなる理由が分かりません。

かなり簡単なプログラムだと思いますが、関数内で出力した場合と、呼び出し側で出力した場合で値が異なります。理由が分からないので教えていただけますか? #include <stdio.h> #include <stdlib.h> Table(int num, double ltable) { double temp[] = { 0.99852, // 1 0.99410, // 2 0.98677 // 3 }; ltable=temp[num]; printf("%f\n",ltable); } main (int argc, char *argv[]) { int num ; double ltable ; num=1; Table(num, ltable); printf("%f\n",ltable); } 実行結果 0.994100 0.000000

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

  • ベストアンサー
  • galluda
  • ベストアンサー率35% (440/1242)
回答No.4

がるです。 メインの質問から少々外れてしまって恐縮ですが。 > void Table(・・・・ > とありますが、voidとはどのようなときに使うのでしょうか? 元の関数が「復帰値を何も返していない」ので、voidにしてみました。 復帰にvoidと書くのは、明示的に「この関数の復帰値はない」と宣言する手法です。 似たようなパターンで「引数がない」事を明示的にする場合、 int function(void) という風な記述をします。これは「引数なし、復帰値はint」であることを明示的にあらわします。

lts107
質問者

お礼

何度もご丁寧にありがとうございました。 理解できました。

その他の回答 (3)

  • edomin
  • ベストアンサー率32% (327/1003)
回答No.3

しばらく携わっていなかったのではずしているかも知れませんが、Table関数を呼び出すときにltableのアドレスを参照して渡さないとltableには何も入力されないと思います。 この場合は、 #include <stdio.h> #include <stdlib.h> double Table(int num) { double temp[] = { 0.99852, // 1 0.99410, // 2 0.98677 // 3 }; printf("%f\n",temp[num]); return(temp[num]); } main (int argc, char *argv[]) { int num ; double ltable ; num=1; ltable = Table(num); printf("%f\n",ltable); } の方が判りやすいと思いますが・・・

lts107
質問者

補足

早速のご回答ありがとうございます。 例文では、戻り値が一つのためreturnの方が簡単に見えるのですが、実際は戻り値が複数あるため、構造体宣言が面倒くさいので、構造体でなく、もっと簡単にできないかぁ、と思った次第です。 複数の戻り値があった場合、さらに簡素な記述方法があり、教えていただけたら幸いです。

回答No.2

main()内で宣言したltable変数と、 Table()内で宣言されているltable変数は別物だからです。 「手元の袋と同じ名前で同じ形で同じ中身の袋を作って渡した。その中に物を入れたのに、手元の袋は空っぽだぞ?」 といった具合です。 プログラム的な言い方をすると「値渡しをしているから」です。 解決方法は「手元の袋の場所を渡して、そこに入れてもらう」、プログラム的には「参照渡しにする」です。

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 取り合えずまず ・引数にデータを格納して戻したいならポインタを渡す 必要があります。 お書きになっているプログラムですと、関数をcallするところの double ltable と関数で受け取っているdouble ltable は別物になりますので、いくら値を設定したところで、call元に値が設定されることはありえません。 関数を void Table(int num, double *ltable) とするか、或いはいっそ double Table(int num) として、復帰値に持ってきたほうがよいように思われます。 なお、前述の場合は Table(num, &ltable); のようにcallする必要がありますし、後述の場合は ltable = Table(num); のようにcallする必要があります。 で、値が異なる理由ですが。 Table 関数内では指定された挙動どおりなので特に解説は必要ないか、と。 mainの double ltable ; は、このプログラムですと「誰も値を設定していない」ので。C及びC++において、設定されていない、宣言されただけの変数の値は「不定」です。今回はたまたま、アサインしたメモリ上が0だったのでしょう。 以上になりますが、また何か不明な点などありましたらお気軽に。

lts107
質問者

お礼

早速のご回答ありがとうございます。 2つ提案していただいた、後者の方は今までやってきており問題なく動作しおりますので、前者の方を質問させえていただきます。 また、異なる理由についても理解できました。 質問ですが、教えていただいたとおりに修正を行うと、関数中の ltable=temp[num]; にて incompatible types in assignment; というエラーになってしまいます。ここも何か修正が必要でしょうか? あと、 void Table(・・・・ とありますが、voidとはどのようなときに使うのでしょうか? ”ポインタ渡しのような、型が指定されてない場合”ってことでしょうか?

lts107
質問者

補足

自己レスです。 関数内のltableを*ltabeにすることで解決しました。

関連するQ&A

  • 四則演算のプログラム

    自力で解きたかったのですが、二時間考えても、とけないので 投稿させていただきます。どこを直せばよいのでしょうか 実行するときは%プログラム名 + 5 12 と入力して実行したいです。加えて参照にしている部分の %の扱いについても教えていただけると幸いです。 #include<stdio.h> #include<stdlib.h> int main(int argc,char *argv[]){ char kigou; double num1,num2; kigou=atof(argv[1]); num1=atof(argv[2]); num2=atof(argv[3]); if(kigou=='+'){ printf("%f+%f=%f\n",num1,num2,num1+num2); } else if(kigou=='-'){ printf("%f-%f=%f\n",num1,num2,num1-num2); } else if(kigou=='x'){ printf("%f*%f=%f\n",num1,num2,num1*num2); } else if(kigou=='/'){ printf("%f/%f=%f\n",num1,num2,num1/num2); } /* else if(kigou=='%'){ printf("%f%%f=%f\n",num1,num2,num1%num2); }*/ else{ printf("Please input +,-,x,%%.\n");} }

  • 計算が合わない

    下のプログラムを実行したところ、1/3の計算結果が0.33333333333333331483になってしまいます。これはどこかプログラムが間違っているのでしょうか? #include<stdio.h> int main(int argc,char **argv){ double d; d=1.0/3.0; printf("%.20f\n",d); }

  • ポインタのポインタ

    #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv){ int i; if(argc != 2) { fprintf(stderr, "Usage: %s vector\n\tEx: %s 11110000\n", argv[0], argv[0]); return 1; } for(i=0;i<8;i++){ if(**argv == '0'){ printf("%d\n",i); } else{ printf("A%d\n",i); } argv++; } return 0; } コンパイルして./a.exe 10010011などと入力しても A0 A1 Segmentation Faultとなります。 どうすれば、 A1 0 ・・・省略 for文で回した8回分、出力が可能になるのか教えてください。 初歩的な質問ですいません。

  • プログラミング(argcとargv)

    入力された数の合計とその計算式を表示するプログラムをつくっています。惜しい(?)ところまでいったのですがその先がなかなか進みません。以下のプログラムのどこを修正したらよいでしょうか?教えてください。 #include <stdio.h> #include <stdlib.h> #define nMAX 10 int main(int argc, char **argv){ int sum = 0; if(argc < 2){ printf("Too few option!\n"); return 1; } int i, n; for(i = 1; i < argc; i++){ n = atoi(argv[i]); sum = sum + n; } printf("%d\n", sum); }

  • この問題が解けません( iдi )

    コマンドプロンプトで prog01 12 + 35 47 と表示する加算プログラムを作りたいのですがわかりません。どなたかおねがいできませんか。 =====prog01========== #include <stdio.h> #include <stdlib.h> main(int argc, char *argv[]) {    int result;    /*ここに処理の記述*/    printf("result = %d\n", result); }

  • main( )

    次の様なプログラムを作りました。 Dosプロンプトを開き、コンパイルで出来た、exeファイルのアドレスを渡しました。 例えば、2と3を引数として渡す時、 2 スペースを押す、 3 enter  の順に行うと、エラーになります。 どの様に、引数を渡すのか操作方法を教えてください。 お願いします。 #include<stdlib.h> #include<stdio.h> int main(int argc, char *argv[]) {    if(argc!=3){     printf("2つの数を指定してください。");     exit(1);    }     printf("%f",atoi(argv[1])+atoi(argv[2]));    return 0; }

  • C言語プログラミングについて

    「要素数10の配列を準備する。 配列の各要素に0.0~1.0の乱数を入れる。 各配列に入力された乱数を出力する。 配列をオリジナル関数hanteiに渡す。 数hantei内において,各要素の値が0.5以上であれば1 , 0.5未満であれば0を出力する。」 C言語でこのような問題があるのですがどのように作ればよろしいのでしょうか? ちなみに以下のように作ってみて、「argcは一度も使用されていない」「argvは一度も使用されていない」とエラー(警告)が出てしまいました。修正、もしくは正しいプログラムを教えてくれませんか? #include <stdio.h> #include <time.h> #include <stdlib.h> #define SIZE 10 int hantei(double num) { return num>=0.5; } int main(int argc,char *argv[]) { double number[SIZE]; int i; srand((unsigned)time(NULL)); for(i=0;i<SIZE;i++) number[i]=(double)rand() / RAND_MAX; //手抜き乱数 for(i=0;i<SIZE;i++) { printf("%f %d\n",number[i], hantei(number[i])); } return 0; }

  • C言語でファイルの内容を strtok関数 を使って数字と文字を分けて

    C言語でファイルの内容を strtok関数 を使って数字と文字を分けて配列に格納したいのですが、うまくできません。 どこが駄目なのかご指摘をお願いします! ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int i=0; int num[10]; char na[10]; fp=fopen(argv[1],"r"); while(fgets(str,sizeof str,fp)!=NULL); tp = strtok ( str, " " ); while(tp != NULL ) { num[i]=atoi(tp); tp = strtok( NULL," "); if ( tp != NULL ){ na[i]=*tp; } i++; } printf("%d\n%s",num[0],na[0]); printf("%d\n%s",num[1],na[1]); fclose(fp); return 0; }

  • Cプログラミング 初歩

    #include <stdio.h> int main (void){ double num; printf("実数を入力して下さい:"); scanf("%lf",&num); printf("あなたは%fと入力しましたね\n",num); return(0); } のプログラミングがコンパイル出来ません↓ printf("あなたは%fと入力しましたね\n",num); をprintf("%f\n",num);のようにすると上手くいくのですが、 どうしたらコンパイルできるか分かる人はいますか?

  • 二行目の*の意味を教えてください。

    #include <stdio.h> int main(int argc, char *argv[]) { int i; for ( i = 0; i < argc; i++ ){ printf("argv[%d]=%s\n", i, argv[i]); } return argc; }  以上プログラムで、二行目の*の意味を教えてくさい。  6行目のargvには*が付いていません!?  よろしくお願いします。