こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

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)
{
staticPoint pget;

pget.x = 2;
pget.y = 2;
pget.h = 30;
pget.w = 40;

return &pget;
}

投稿日時 - 2011-02-14 00:24:45

QNo.6521165

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

ANo.1

たとえば、get()の実装を
Point *get(void)
{
static Point pget;
static int count_visited = 0;

count_visited++;

pget.x = count_visited;
pget.y = 2;
pget.h = 30;
pget.w = 40;

return &pget;
}
と、取得のたびに確実に値が変わるようして、さらに、
int main(void){
Point *get1;
Point *get2;

func(&get1);
func(&get2);

printf("get1.x:[%d]\n",get1->x);
printf("get2.x:[%d]\n",get2->x);
return 0;
}
としてみれば、何が問題か理解できると思います。

修正のパターンとしては、
(1)malloc()で領域を確保する
Point *get(void)
{
Point* pget = NULL;
pget = (Point*)malloc(sizeof(Point));
if (pget != NULL){
(値の設定)
}
return pget;
}
→この場合、get()を利用している箇所あるいはその外側できちんと領域を確保できたか確認する必要があり、また受け取った領域をfree()する必要がある。
(2)引数で値を受け取る領域を渡す
Point *get(Point* pget)
{
if (pget != NULL){
(値の設定)
}
return pget;
}
→この場合、get()を利用している箇所あるいはその外側で領域を用意する必要があり、またその領域はget()内で変更されることを認識している必要がある。
の2パターンが考えられます。

ちなみに、(2)の場合、その呼び出しはたとえば
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){
if(pw != NULL) get(pw);
}
となります。

まあ、構造体にポインタが含まれていないので、func()の戻り値も変えていいなら自分は
int main(void){
Point get = func();
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;
}

Point func(){
Point point;
get(*point);
return point;
}
としますが。

投稿日時 - 2011-02-14 01:51:33