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

解決済みの質問

C言語:構造体、自作関数についての質問

こんばんは
C言語の問題を提示されてなんとか作成していますが構造体と自作関数の変数の値を返したりするのが上手くいきません。

問題
「(1)x座標およびy座標のペアとして構成される構造体pointを定義せよ(両座標は整数であるとする)
 (2)x座標およびy座標のメンバに値を設定し、その構造体を返す関数
 struct point pointof(int a,int b){………}を作成せよ。
 (3)二つの座標a,b間の距離を計算する関数
 double distanceod(struct point a,struct point b);
を作成せよ。
 ※sqrt関数を使用せよ」
という問題です。メンバについてもいまいちよくわかりません。
どこでintを使うのか、またmainに値を返すやり方も上手くいかずコマンドプロンプトにはねられてばかりです。
どなたか解説おねがいしますm(_ _)m

投稿日時 - 2007-05-22 20:06:13

QNo.3021781

困ってます

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

> 1:C99とはなんですか?

検索してみてください。すぐ詳しい説明が見つかるはずです。

> 2:自作関数の呼び出しでdestanceof(main1,main2)とありますが
>  ()無いは関数に与える数字との認識が私にはあります。

それは事実誤認ですね。関数の引数には、配列型以外のどんなオブジェクト型でも指定することができます。(配列型も指定できるように見えますが、それが実際にはポインタ型であることは、どんな入門書にも書いているはずです。)

>  参考書でも構造体で似たようなものが載っていましたが説明が
>  少なく、理解できませんでした。できればここの部分についての
>  説明もお願いできないでしょうか?m(_ _)m

構造体は、整数型やポインタ型などと同じで、値として関数に渡すことも、値として関数から返すこともできます。大昔のCコンパイラはこれができませんでした。ですから、今でも構造体と見ればポインタで受け渡ししなければならないものと、短絡的に考える方は少なくありません。もっとも、大きな構造体を値で受け渡しするのは効率が悪いので、ポインタを使った方がよいのは確かです。

投稿日時 - 2007-05-23 00:18:17

ANo.8

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

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

回答(9)

ANo.9

ANo.5です。
明らかにバグです。

struct point *pointof(int a,int b)
{
  struct point pt;



struct point *pointof(int a,int b)
{
  static struct point pt;

です。

失礼しました。

投稿日時 - 2007-05-23 06:17:14

お礼

ありがとうございましたm(_ _)m
なんとか動くものに仕上がりました。

値の返し方が理解できました。

投稿日時 - 2007-05-23 19:59:31

ANo.7

★アドバイス
・構造体 point には座標の x、y をメンバにします。(1)より。
 つまり、
 struct point {
  int x;
  int y;
 } point;
 
 その後、struct point pointof( int x, int y ); という関数で構造体 point に x、y を
 セットします。セットした構造体をそのまま戻せばよい。
 つまり、
 struct point pointof( int x, int y ) ←仮引数は a、b よりも x、y の方が分かりやすいよ。多分。
 {
  struct point ret; ←ここで構造体を宣言。
  
  ret.x = x;
  ret.y = y;
  return ret; ←ここで構造体をそのまま返す。
 }
 
 (3)の distanceod() 関数はご自分で作成して下さい。構造体の返し方は上の pointof() を参考に!
・次は main() 部分です。
 下のサンプルをどうぞ。

サンプル:
int main( void )
{
 struct point a, b; ←ここで a点、b点の構造体を宣言
 int x, y;
 
 printf( "点aのX座標=" ); scanf( "%d", &x ); printf( "\n" );
 printf( "点aのY座標=" ); scanf( "%d", &y ); printf( "\n" );
 a = pointof( x, y ); ←a 点の代入
 
 printf( "点bのX座標=" ); scanf( "%d", &x ); printf( "\n" );
 printf( "点bのY座標=" ); scanf( "%d", &y ); printf( "\n" );
 b = pointof( x, y ); ←b 点の代入
 
 printf( "a, bの間の距離=%.2lf\n", distanceod(a,b) ); ←記入はこれ。構造体を渡せ!それだけだ。
 return 0;
}

最後に:
・もう少し関数の作成方法をテキストなどで見直して下さい。
 特に構造体を引数で渡す方法、構造体を戻り値として返す方法などです。
・あと構造体のなども見直して下さい。
>return input1, input2; など色々記入していました*/
 ↑C言語では、戻り値は1つです。いっぺんに複数の変数などを戻せません。
 Java?、JavaScript では複数個を配列で返せますが、C 言語では出来ません。
・以上。参考に!

投稿日時 - 2007-05-22 23:51:26

ANo.6

議論するつもりはないですが、捨て置けないので指摘します。
#5の回答の(2)は明らかな間違いです。というより、この程度なら無理にポインタで返すより値で返した方が簡単です。

投稿日時 - 2007-05-22 22:15:37

お礼

いくつもの回答感謝の極みです。
ありがとうございますm(_ _)m

回答を見ている過程でもいくつかの質問があります。
1:C99とはなんですか?
2:自作関数の呼び出しでdestanceof(main1,main2)とありますが
 ()無いは関数に与える数字との認識が私にはあります。
 参考書でも構造体で似たようなものが載っていましたが説明が
 少なく、理解できませんでした。できればここの部分についての
 説明もお願いできないでしょうか?m(_ _)m

投稿日時 - 2007-05-22 23:59:46

ANo.5

(1)
構造体は
struct タグ{
  メンバ
  :
};

なので、タグをpointとし、メンバにx座標、y座標をintで定義する。よって、
struct point{
  int x;
  int y;
};
となる。

(2)
struct point *pointof(int a,int b)
{
  struct point pt;

  pt->x = a;
  pt->y = b;
  return &pt;
}

この関数を呼び出す前に座標をscanfで入力する。
struct point a,b;
:

printf( "座標a: " );
scanf( "%d %d", &x, &y );
a = *pointof( x, y );
printf( "座標b: " );
scanf( "%d %d", &x, &y );
b = *pointof( x, y );

(3)
2点間の距離は
d^2 = (x2-x1)^2 + (y2-y1)^2
であるから

double distanceod(struct point *a, struct point *b)
{
  double x, y, d;

  x = b->x - a->x;
  y = b->y - a->y;
  d = sqrt( x * x + y * y );
  return d;
}

となる。よって、
struct point a,b;
double  d;

d = distanceod( &a, &b );
printf("a,bの間の距離=%.2f",d);

投稿日時 - 2007-05-22 22:03:47

ANo.4

まず、pointof関数ですが、引数a, bの意味は何でしょう?
もしそれぞれがx, y座標であれば、pointofの中でscanfを呼ぶのではなく、

struct point pointof(int a, int b)
{
 return (struct point){ a, b }; // 注意) C99でない場合は自分で考えること!
}

でよいのでは?
distanceof関数の呼び出しは、おそらく

distanceof(main1, main2)

でよいかと思います。

ところで、#3の方が指摘されているように、C99ならsqrtを使うよりhypotを使う方が簡単ですね。そうではなく、処理系に依存しない実装にするならsqrtを使うのも仕方ないでしょうけど。

投稿日時 - 2007-05-22 21:55:50

ANo.3

本当にわからないんだったら, 表示されたものを「一字一句そのまま」こちらに出してください.
しかし, 距離を計算するのに sqrt 使わせるかねぇ. hypot を使えばいいのに....

投稿日時 - 2007-05-22 20:59:39

ANo.2

何をどうやって、どこがどのようにうまくいかないのか。
それを書かないと課題の丸投げとして削除されちゃいますよ。

> mainに値を返すやり方も上手くいかずコマンドプロンプトにはねられてばかりです。

コマンドラインからコンパイルをしていて、コンパイラに怒られた、という意味でしょうか? 開発環境は何を使ってますか?

いまいちよくわからない、なら、「自分はこう思うんだけどコンパイラには違うっていわれた」というところまで書いてくださいね。

投稿日時 - 2007-05-22 20:39:57

お礼

返信ありがとうございますm(_ _)m
こういった質問は初めてなのでそれについてもアドバイスいただけるとありがたいです。

#include<stdio.h>
#include<math.h>

#define sqr(n) ((n)*(n))

struct point{
int a;
int b;
};

struct point pointof(int a,int b) /*座標を入力する部分*/
{
struct point input1,input2;
printf("点aの座標="); scanf("%d",&input1.a);
printf("点aの座標="); scanf("%d",&input1.b);
printf("点bの座標="); scanf("%d",&input2.a);
printf("点bの座標="); scanf("%d",&input2.b);

return /*ここの値の返し方が分かりません
       return input1,input2; など色々記入していました*/
}

/*座標との距離の換算をする部分*/
double distanceod(struct point a,struct point b)
{
return(sqrt(sqr(b.a-a.a)+sqr(b.b-b.a)));
}
int main(void)
{
struct point main1.main2;

pointof;

/*以下のdistanceod()の記入の仕方が分かりません
そもそも何を入れればいいのか… */
printf("a,bの間の距離=%.2f",distanceod() )
return 0;
}

このような感じです。
構造体と自作関数の値の交換(?)の仕方がよくわかりません。
コンパイルでもそこで引っかかったり、通っても値が-1.$のような
かんじになってしまいます。
プログラミングは仕事で覚えています。
今年の4月から始めたので用語などあまり理解できず分かりにくい
質問になってしまいもうしわけないですm(_ _)m

投稿日時 - 2007-05-22 21:23:35

ANo.1

まずは、その上手くいかなかったものを補足してください。
話はそれからです。

投稿日時 - 2007-05-22 20:14:56

あなたにオススメの質問