• 締切済み

変数の有効範囲について

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% (2127/6290)
回答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