• 締切済み

変数の有効範囲について

C言語の課題について教えてください [課題] 以下の関数がある。各関数の引数、変数は自由に設定していい ・int main() ・void Wrapper() ・void setdate(int *pset) { *pset = 10; } ・int *getdate() 問題 (1)main関数から、Wrapper関数を経由して、setdate関数を経由し値を取得し、表示する 意図としては、main内で、実態を宣言し、setdate関数内で値を代入し、main関数内で表示 (2)main関数から、Wrapper関数を経由して、getdate関数を経由し値を取得し、表示する 意図としては、main内でポインタを宣言し、getdate内で実態を宣言しそのアドレスをかえし、main関数内で表示 以下が考えたソースになります #include <stdio.h> int *getdata(void) { static int num = 100; printf("num[%p]\n",&num); } void setdata(int *p) { *p = 1; } void Wrapper(int *pw, int type) { if (type == 0) { *pw = *getdata(); } else { setdata(pw); } } int main(void) { int *get, set; Wrapper(get, 0); printf("get[%d]\n", *get); Wrapper(&set, 1); printf("set[%d]\n", set); return 0; } setdateの関数に関してはわかるのですが、getdateの関数は、実施したい内容とは異なると思うので、修正していただきたいです。 このやり方だと、参照しているアドレスはmain内で宣言した場所でありget関数で宣言した場所ではないと思うのです。

みんなの回答

  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.3

これは関数内の内部static宣言の練習課題でしょうか? (あまりいい課題ではない気がしますが…) コードそのものは、コンパイラからのエラーメッセージ等を参考に修正してみてください。 以下はヒントレベルのアドバイスを記します。 最初に、num, get, set, type などの変数名は、コンパイラの予約後になっていないかどうか調べてみてください。 多分、nm, gd、sd、tp など予約後になさそうな名前にする方が安全です。 以下は、混乱のないように質問者殿が定義した変数名、関数名そのままで説明します。 int *getdata() の関数で、戻り値をretrun( num ) として返す必要があります。 Wrapper()を経由しなければ、main()で定義した get に、getdataの戻り値を入れるだけ(下記)、 get = getdata()  ← numのポインター値がgetに代入され、以降 get は num の内容を参照することになる。 なのですが、 Wrapper() 関数で中継しなければならず、かつWrapper()の定義は void となっているので、 getdata() 内に実態がある num のポインターを受け渡す仕組みが必要になる気がします。。即ち、ポインターのポインターを返すというちょっとやっかいな処理が必要です。(面倒くさい…) 考え方としては、Wrpper() の定義を下記の様にして、 void ( int *ps, int **pg, int type ) type が 0の時は、     pgに getdata()の戻り値、(即ちnumのポインター値)を返す。 type が 0以外の時は、  psを setdata()の引数として与え、値を代入させる。 という処理になるかと思います。(あまり綺麗な処理ではないですが、課題の前提を考えるとこんなもんでしょうか。) Wrapperが int *Wrapper() で定義出来るなら、戻り値に getdata() の戻り値をそのまま渡せば良いので、もっと簡単に出来ますが、これもあまり綺麗ではないですね。 具体的には、下記の様になるかと思います。(自信なし) void Wrapper( int *ps, int **pg, int type ) {   if (type == 0 )     *pg = getdata();   else     setdata( ps ); } main()の方は、下記の様になります。 void main( void ) {   int **get, set;   Wapper( get, &set, 0 ):   printf( "get[%d]\n",**get );   Wapper( get, &set, 1 );   printf( "set[%d]\n, set ); } 手元にコンパイラがないので、自信はありませんが、こんな様な感じになるのではないかと思います。 いずれにしても、コンパイルしてエラーメッセージなどを見ながら、進めてみてください。(場合によって、cast などが必要になるかも知れません) ご参考に。

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

>int *getdata(void) ここで、getdata関数はint型へのポインターを呼び出し元に返すと言っているのですから、 >{ >static int num = 100; >printf("num[%p]\n",&num); >} そのとおりにしてみてはどうでしょうか。

  • myuki1232
  • ベストアンサー率57% (97/170)
回答No.1

これだとそもそもコンパイルが通らないでしょう。 問題文にあるとおり、getdata関数を 1. 実体を宣言 2. 1. のアドレスを返す ように修正し、Wrapper関数でそれを代入するようにしてください。

meganesa
質問者

補足

すいません。 【Wrapper関数でそれを代入するようにしてください。】 この部分がよくわからないのですが、 具体的にソースで教えていただきたいです。

関連するQ&A

  • Cのローカル変数でstatic以外の使い方?

    C言語の課題について教えてください [課題] 以下の関数がある。各関数の引数、変数は自由に設定していい ・int main() ・void func() ・Point *get() { /* 構造体のアドレスを返す */ } ・構造体 typedef struct { int x; int y; int h; int w; }Point; 問題 main関数から、func関数を経由して、get関数を経由し値を取得し、表示する 以下が考えたソースになりますが、これだと、 ローカル変数でstaticを使っているので、get関数が固定値ではなく、 取得のたびに値が変わるような場合には、だめだといわれました。 考えたのですがよくわからないので、どういう場合に駄目なのかと、 どのように修正すればいいのか教えてください。 #include <stdio.h> typedef struct { int x; int y; int h; int w; }Point; void func(Point **); Point *get(); int main(void){ Point *get; func(&get); printf("get.x:[%d]\n",get->x); printf("get.y:[%d]\n",get->y); printf("get.h:[%d]\n",get->h); printf("get.w:[%d]\n",get->w); return 0; } void func(Point **pw){ *pw = get(); printf("Wrapper: pw==%p\n",pw); } Point *get(void) { static Point pget; pget.x = 2; pget.y = 2; pget.h = 30; pget.w = 40; return &pget; }

  • Cのポインタについて(関数への値渡し)

    C言語のポインタに関する質問です。関数に引数を渡す方法として以下の誤ったswap関数でなぜだめなのかいまいち得心できません。わかりやすくかみくだいて説明していただけると有り難いです。 できましたら、トレースともうしますか、変数の値の動きを詳細に段階的にプログラムの流れに沿って追っていって、だからこうなんだよ、みたいな解説がいただけたら有り難いです。わがままいってすみません。 /* 誤ったswap関数の宣言 */ void swap(int x, int y); int main(void) { int num1 = 5; int num2 = 10; printf("変数num1の値は%dです。¥n", num1); printf("変数num2の値は%dです。¥n", num2); printf("変数num1とnum2の値を交換します。¥n", num1); swap(num1, num2); printf("変数num1の値は%dです。¥n", num1); printf("変数num2の値は%dです。¥n", num2); return 0; } /* 誤ったswap関数の定義 */ void swap(int x, int y) { int tmp; tmp = x; x = y; y = tmp; } ---------- /* swap関数の宣言 */ void swap(int *pX, int *pY); int main(void) { int num1 = 5; int num2 = 10; printf("変数num1の値は%dです。¥n", num1); printf("変数num2の値は%dです。¥n", num2); printf("変数num1とnum2の値を交換します。¥n", num1); swap(&num1, &num2); printf("変数num1の値は%dです。¥n", num1); printf("変数num2の値は%dです。¥n", num2); return 0; } /* swap関数の定義 */ void swap(int *pX, int *pY) { int tmp; tmp = *pX; *pX = *pY; *pY = tmp; }

  • グローバル変数について

    ◎1--------------------------------- #include<stdio.h> void func(void); int glb; int main(void) { int a=20; glb=30; printf("main a=%d glb=%d\n",a,glb); func(); return 0; } void func(void) { int b=88; printf("func b=%d glb=%d\n",b,glb); } ------------------------------------- ◎1の実行結果----------------------- main a=20 glb=30 func b=88 glb=30 ------------------------------------- ◎2--------------------------------- #include<stdio.h> void func(void); int glb; int main(void) { int a=20; func(); printf("main a=%d glb=%d\n",a,glb); return 0; } void func(void) { int b=88; int glb=30; printf("func b=%d glb=%d\n",b,glb); } ------------------------------------- ◎2の実行結果----------------------- func b=88 glb=30 main a=20 glb=0 ------------------------------------- 以上2つのプログラムで、◎1は参考書を参考に作成したものです。 ◎1のプログラムで、グローバル変数glbの値をmain( )関数内で設定していたので、次に◎2のようにfunc( )という関数プロトタイプ内で、グローバル変数glbの値を設定し、main( )関数内のprintf文でも表示させようと思ったら、「glb=0」となってしまいました。 なぜこのようになってしまうか、教えてもらえたら嬉しいです。

  • 変数の使い方

    お聞きしたいのですが、下記の main関数、getaverage関数の両方で 変数averageを宣言してますが、 名前は同じだが、まったく別変数と考えて良いのですか? 教えてください。 #include <stdio.h> int getaverage(int data[10]); int main(void) { int average,array[10] = {15,78,98,15,98,85,17,35,42,15}; average = getaverage(array); printf("%d\n",average); return 0; } int getaverage(int data[10]) { int i,average = 0; for (i = 0;i < 10;i++) { average += data[i]; } return average / 10; }

  • C++ なのですがエラーが消えません

    課題のC++プログラムのエラーが消えません,教えてください. 10個の数値を入力し並び替えるプログラムなのですが並び替え部分以外は先生作成のプログラムです. どうかお願いいたします. #include <stdio.h> #define MAX 10 #define OK 0 void inputnum(int num[]); void sortnum(int num[]); void outputnum(int num[]); main(){ int num[MAX]; printf("番号 氏名\n"); inputnum(num); sortnum(num); outputnum(num); return(OK); } void inputnum(int num[]){ int i; for(i=0;i<MAX;i++,num[i]){ printf("数値%d = ", i+1); scanf("%d",&num[i]); } printf("数値入力完了\n"); } void sortnum(int num[]){ int tmp,p,q; for(p = 0; p < 9; p++){ for(q = p + 1; q < 10; q++){ if(num[p] > num[q]){ tmp = num[p]; num[p] = num[q]; num[q] = tmp; } } } printf("並び替え完了\n"); void outputnum(int num[]){ int i; for(i=0;i<MAX;i++){ printf("数値%d = %d\n",i+1,num[i]); } printf("数値出力完了\n"); }; [エラー  Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland 1142122.c: エラー E2140 1142122.c 46: ここでは宣言はできない(関数 sortnum ) エラー E2141 1142122.c 46: 宣言の構文エラー(関数 sortnum ) エラー E2134 1142122.c 54: 複合文に } がない(関数 sortnum ) *** 3 errors in Compile ***]

  • 戻り値を返す関数の前に(void)を付ける

    今日会社で 変数 = (void)戻り値のある関数 #具体的な例としては下記一例を参照 と、ソースで書かれているものがあったのですが、 コメント等では、 「戻り値を明示しないときに(void)を付けて使用する」 と、書いてあります。 戻り値のある関数の前で(void)を付けると、戻り値が明示されなくなるのでしょうか?? または、このような動作にはならないのでしょうか。 自分自身、ソースの内容をうる覚えになっておりますので、 確認をしながらアップしていきたいと思いますので、 宜しくお願い致します。 /*一例*/ ・num1とnum2を足した値を返す int PlusPoint(int num1 , num2); ・PlusPointの値を格納する int Sum ◇ソース◆ #include <stdio.h> #include "Plus.h" int main(void) { int Sum; Sum = (void)PlusPoint; if(Sum == 2) { printf("false"); exit(0); } printf("true"); return 0; } *PlusPoint関数は外部で定義されている *プロトタイプ宣言はPlus.hに定義されいるものとする

  • 分割コンパイルの初歩

    C言語ですが、.hに実装を書くのは避けたほうが良いといわれます。 私は main.c define.h aaa.h bbb.h みたいなスタイルでコードを書いていました。 まずdefine.hでグローバル変数や、マクロなどの宣言を まとめて行い、ほかの.hやmain.cでも使えるようにして いました。 しかし、以下のような状況のとき、どのように分割すれば 良いのかが分かりません・・・。 たとえば、以下のように、マクロNUM、変数a,bをすべてのファイルで共有して使えるように分割コンパイルするにはどのようにコードを書き直せば良いのでしょうか? //--------------main.c------------------ #include "define.h" #include "aaa.h" #include "bbb.h" int main( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM);   aaa();   bbb();   return 0; } //------------define.h------------------ #define NUM 100 int a = 10; int b = 20; void aaa( void ); void bbb( void ); //------------aaa.h------------------ void aaa( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM); } //------------bbb.h------------------ void bbb( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM); }

  • 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() ); }

  • コンパイルエラー

    コンパイルしても、12行目(printf("%d番目の整数を入力してください。"i+1);が、関数呼び出しに)がないとでます。でもどこが間違っているか分かりません。 教えてください。お願いします。 #include <stdio.h> int main(void) { int num; int sum=0; int i; for(i=0; i<10; i++){ printf("%d番目の整数を入力してください。"i+1); scanf("%d", &num); sum+=num; } printf("合計は、%dです。\n", sum); return(0); }

  • return 1

    #include<stdio.h> int fact(int num); int main(void) { int i; printf("Input figure freely:"); scanf("%d", &i); printf("%d", fact(i)); return 0; } int fact(int num) { if(num>0){ return num * fact(num-1); }else{ return 1; } } -------------------------------------------- 上のプログラムは再帰呼び出しを使った階乗計算の プログラムです。 func()関数内のreturn 1の意味をどなたか教えて いただけないでしょうか?