• ベストアンサー

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

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

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.8

> 1:C99とはなんですか? 検索してみてください。すぐ詳しい説明が見つかるはずです。 > 2:自作関数の呼び出しでdestanceof(main1,main2)とありますが >  ()無いは関数に与える数字との認識が私にはあります。 それは事実誤認ですね。関数の引数には、配列型以外のどんなオブジェクト型でも指定することができます。(配列型も指定できるように見えますが、それが実際にはポインタ型であることは、どんな入門書にも書いているはずです。) >  参考書でも構造体で似たようなものが載っていましたが説明が >  少なく、理解できませんでした。できればここの部分についての >  説明もお願いできないでしょうか?m(_ _)m 構造体は、整数型やポインタ型などと同じで、値として関数に渡すことも、値として関数から返すこともできます。大昔のCコンパイラはこれができませんでした。ですから、今でも構造体と見ればポインタで受け渡ししなければならないものと、短絡的に考える方は少なくありません。もっとも、大きな構造体を値で受け渡しするのは効率が悪いので、ポインタを使った方がよいのは確かです。

その他の回答 (8)

  • DT200
  • ベストアンサー率38% (63/164)
回答No.9

ANo.5です。 明らかにバグです。 struct point *pointof(int a,int b) {   struct point pt; は struct point *pointof(int a,int b) {   static struct point pt; です。 失礼しました。

hisetu_001
質問者

お礼

ありがとうございましたm(_ _)m なんとか動くものに仕上がりました。 値の返し方が理解できました。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.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 言語では出来ません。 ・以上。参考に!

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.6

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

hisetu_001
質問者

お礼

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

  • DT200
  • ベストアンサー率38% (63/164)
回答No.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);

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.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を使うのも仕方ないでしょうけど。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

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

  • Interest
  • ベストアンサー率31% (207/659)
回答No.2

何をどうやって、どこがどのようにうまくいかないのか。 それを書かないと課題の丸投げとして削除されちゃいますよ。 > mainに値を返すやり方も上手くいかずコマンドプロンプトにはねられてばかりです。 コマンドラインからコンパイルをしていて、コンパイラに怒られた、という意味でしょうか? 開発環境は何を使ってますか? いまいちよくわからない、なら、「自分はこう思うんだけどコンパイラには違うっていわれた」というところまで書いてくださいね。

hisetu_001
質問者

お礼

返信ありがとうございます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

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

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

関連するQ&A

  • 構造体の要素すべてに対する四則演算の方法を教えてください.

    構造体の要素すべてに対する四則演算の方法を教えてください. たとえば、 2点a,bの座標成分x,y,zをそれぞれの座標ごとに足す方法を教えてください. 下のようにx,y,z成分を持ったa,bがあります。 struct point{ int x; int y; int z; }; struct point a; struct point b; struct point c; この場合, c=a+b; と書くことができず, それぞれの成分ごとに以下のように足さなくてはなりません. c.x=a.x+b.x; c.y=a.y+b.y; c.z=a.z+b.z; この方法でできるのですが, 非常に効率的でないのでなにかもっと簡単に記述する方法を教えてください. お願いいたします.

  • 構造体の中の構造体

    typedef struct number{ int x; struct number *next; }Num; 初心者な質問で申し訳ないんですが、構造体の中に構造体があるのはどう解釈していいんでしょうか? typedef struct number{ int x; int y; }Num; の場合はNum a,b;がint a.x,a.y,b.x,b.yとなるのは分かるんですが・・・

  • C言語に関して質問です。構造体について

    構造体についての課題を出されたのですが、よくわかりません。教えてください。 問.複素数の構造体を作成し、その構造体変数2つを引数にもつ四則演算の関数を作成せよ。ただし、それぞれの四則演算の構造体を作成し、main関数内で、(a + bi) + (c + di)の形にし、a=2, b=3,c=4,d=5とすること。 この問題で以下までしか作れませんでした。解説を付けてソースをお願いします。 戻り値の型あってますか? #include<stdio.h> typedef struct{ double x,y; }Complex; void add(Complex z1 , Complex z2); void sub(Complex z1 , Complex z2); void multi(Complex z1 , Complex z2); void divide(Complex z1 , Complex z2);

  • C言語の構造体について

    構造体を勉強している所なのですが変数をまとめられるのは分かりましたがどのサイトを見てもいまいち使い所がわかりません。 struct test { int a; int b; int c; }testtest; testtest.a = 0; testtest.b = 1; testtest.c = 2; 例えば上記のような構造体を作成するとします。 私の見たサイトでは構造体で宣言はまとめられても初期化する事はできないと書いてありました。 下記のように変数を普通に宣言&初期化するよりも手間がかかってしまっていると思うのですが私の考えが及ばない何か別の使い方または処理が早くなったりする事があるのでしょうか?。 int a = 0; int b = 1; int c = 2;

  • C言語の構造体の問題が分かりません

    以下のソースコードを使って次の2つの問題に答えよ。というものです。 #include<stdio.h> #include<math.h> struct cartes{ double x,y; /*x-axis,y-axis*/ }; struct polar{ double r,th; /*radius,theta*/ }; struct cartes p2c(struct polar a) { struct cartes d; d.x=a.r*cos(a.th); d.y=a.r*sin(a.th); return d; } struct polar c2p(struct cartes b) { struct polar e; e.r=sqrt(b.x*b.x+b.y*b.y); e.th=atan(b.y/b.x); return e; } void main(void) { struct cartes c; struct cartes c1={1,1},c2={1,1.7320508},c3={1.7320508,1}; struct polar p1,p2,p3; struct polar p={1.41421356,0.7853982}; p1=c2p(c1); p2=c2p(c2); p3=c2p(c3); c=p2c(p); printf("radius=%lf, theta=%lf(radians)\n",p.r,p.th); printf("x-axis=%lf, y-axis=%lf\n",c1.x,c1.y); printf("radius=%lf, theta=%lf(radians)\n",p2.r,p2.th); printf("x-axis=%lf, y-axis=%lf\n",c.x,c.y); } 1.2次元直行座標における2点の座標を与えられて、2点間の距離を求める関数を作り、正しく動作するようにせよ。 2.複素数を構造体として定義せよ。次に2つの複素数変数を受けてその和、差、積、商を求める関数を作り、正しく動作するようにせよ。 以上2つの問題についてソースコードを書いてご説明いただければ幸いです。

  • 関数から構造体を返す一般的な手法は

    たとえば下のような平面上の点を表す構造体があって、 typedef struct { const int x; const int y; } Point; 2点間の中心を計算する関数を書くとします。 この場合、計算結果をどのように返せばよいでしょうか。 「ただ動けばよい」コードを書くことはできるのですが、 私が知りたいのは、どのような書き方が一般的かということです。 構造体の要素が const なので、 下のコードはコンパイルできません。 void center(Point* result, Point* p1, Point* p2) {  result->x = (p1->x + p2->x) / 2;  result->y = (p1->y + p2->y) / 2; } 新しいオブジェクトを作ってコピーする? void center(Point* result, Point* p1, Point* p2) {  Point p = { (p1->x + p2->x) / 2, (p1->y + p2->y) / 2 };  memcpy(result, &p, sizeof(Point)); } この例のような小さい構造体であれば、 オブジェクトをまるごとリターンしてもよい? Point center(Point* p1, Point* p2) {  Point p = { (p1->x + p2->x) / 2, (p1->y + p2->y) / 2 };  return p; } あるいは、そもそも構造体の要素を const にする手法は C言語では一般的でないのでしょうか? どうかご教授願います。

  • C言語 構造体配列について

    6人分の小テストの点数を記録し,平均値などを計算するプログラムを作成している. 以下の手順と条件に従ってプログラムを作成. 手順 (1) 氏名(name[100], char 型) と点数( score , int 型) をメンバにもつ構造体「struct_TEST」を(main 関数の外で)定義. (2) struct _TEST 型構造体配列 element[6] を定義. (3) キーボードから氏名(ローマ字でよい)と点数を入力する処理を6 回繰り返す. (4) 平均点を計算して画面表示. (5) 最高点を出した人の名前と点数を画面表示. (6) 平均点に満たない人の名前と点数を画面表示. 条件 (3)~(6)の処理には以下に示す関数を利用する. (3) ・・・ 氏名と点数を入力する処理をn 回繰り返す関数 void input_score( struct _TEST *a, int n ) (4) ・・・ n 個の構造体配列に対して平均を計算し,平均点を返す関数 double calc_ave( struct _TEST *a, int n ) (5) ・・・ n 個の構造体配列に対して最高点を算出し,そのユーザの配列番号を返す関数 int calc_max( struct _TEST *a, int n ) (6) ・・・ n 個の構造体配列に対して平均点に満たない人の名前と点数を画面表示する関数 void show_under_ave( struct _TEST *a, int n ) C言語の構造体が良く分かっていません。 こういった条件が多いと考えづらく分からなくなります。 考えても分かっていないので困っています。 誰かすみませんが解答を教えて下さい。

  • 構造体の代入と比較

    構造体のコピーは以下のようで正しいと思いますが、 struct A { int a; }; struct x, y; x.a=1; y = x; 構造体の比較は if (x != y)ではいけないのでしょうか? 構造体に限らずクラスも同じ考えでしょうか?

  • 複数のライブラリをリンクするときに構造体が衝突する

    C++,開発環境はVisual Studio Professional 2013です, ライブラリ1にxy座標の構造体 struct point { int x; int y; }; を定義しています. ライブラリ2にも全く同じ構造体を定義しています. ここで,あるプロジェクトからこれら2つのライブラリをリンクしようとしたら, error C2011: 'point' : 'struct' 型の再定義 というコンパイルエラーが出ます. ライブラリ1とライブラリ2にpoint構造体が記述された共通用のヘッダを参照させるという方法をとれば解決できるのでしょうが,この方法以外でこのエラーをなんとか回避する方法はないでしょうか. 構造体宣言は只の宣言であって実体をもたないため,中身が同じであればいくら記述が重複しても問題はないと聞いたことがあったので大丈夫だと思っていました. また,ライブラリ1とライブラリ2のpoint構造体の名前それぞれpoint1,point2にするなど違うものにするという方法でも回避できるのでしょうが,下記のメインコード内でコメントアウトされている部分のように,構造体の中身が全く同じなので互換性を持たせられるようにしたいのです. ちなみに,ライブラリ1,2はコンソールアプリケーション・空のプロジェクトで作成したあと,ソリューションのプロパティで「構成の種類」を「スタティックライブラリ(.lib)」にするという手順で作成しています. 以下,簡略コード ====ライブラリ1==== ----lib1.h---- #ifndef _H1_ #define _H1_ struct point { int x; int y; }; void print_lib1(struct point p); #endif ----lib1.cpp---- #include "lib1.h" #include <iostream> void print_lib1(struct point p) { std::cout << "lib1 : " << p.x << ", " << p.y << std::endl; } =====ライブラリ2====== ----lib2.h---- #ifndef _H2_ #define _H2_ struct point { int x; int y; }; void print_lib2(struct point p); #endif ----lib2.cpp---- #include "lib2.h" #include <iostream> void print_lib2(struct point p) { std::cout << "lib2 : " << p.x << ", " << p.y << std::endl; } ===メインコード=== ----main.cpp---- #include "../../lib1/lib1/lib1.h" #include "../../lib2/lib2/lib2.h" int main(void) { struct point val; val.x = 2; val.y = 3; print_lib1(val); //print_lib2(val); }

  • 構造体の自作関数内で入力した値の返し方

    こんばんはm(_ _)m C言語の構造体に関する質問です。 (当方初心者なので用語等見苦しい点があると思いますがご了承&指摘をお願いします。) 日付を元号に直したりする構造体のプログラムでmain関数ではなく自作関数内で値を入力する問題を解いていまして… #include<stdio.h> typedef struct{ int year; int month; int day; }date; date put_date(date x) /*ここで日付を入力*/ { date x;       printf("年:"); scanf("%d",x.year); printf("月:″); scanf("%d",x.month); printf("日:"); scanf("%d",x.day); return x; } int main(void) { date x; x.year=0; /*問題では関数外で宣言した変数では足りないため         に他の自作関数で変数を使いまわすために必要な処         理で初期化しました。*/ put_date(x);     gen(x); /*西暦の日付を元号で表す自作関数でここへput_date        で取得したx,y,zを送りたいのですがmainに来た時点        でput_dataで入力した値が出ませんでした。(元号に        直す関数は省略いたしました)*/ } put_date内でprintfしましたところx,y,zの値が入力した通りに出ましたが、main内ではx.year=0,x.month=12,x.day=0という値になってしまいます。 put_dateで入力した値をmain関数内だけでなく他の自作関数内でも使用したいのですがどうすればよろしいでしょうか?