質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • C

    4641questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C言語で衝突を判定するプログラムを書きましたが、もっと分かりやすく書けますか。

受付中

回答 6

投稿

  • 評価
  • クリップ 0
  • VIEW 414

teityura

score 40

制限時間15分の試験で、C言語の衝突を判定するプログラムを
手書きで書いてください。と言われたとして、
下記のようなコードを書いたとします。

実行してみれば、手元で円Aと円Bの図を描きつつ、
衝突判定のイメージを追いやすいのですが、
コードで見ると、関数に分けたりした方が見やすくなるような、
これくらいの長さだと、これでちょうどいいような、、、。

もし皆さんが、
同様の状況に置かれたとしたら、どんなコードを書きますか?

#include <stdio.h>

void main(void) {
    int r1 = 2;
    int r2 = 3;
    printf("座標A(?, ?), 座標B(?, ?) を中心とする、\n");
    printf("円A(半径=%d), 円B(半径=%d) が衝突しているか判断します。\n\n", r1, r2);

    int x1, y1;
    printf("座標Aを入力してください。\n?, ?: ");
    scanf("%d, %d", &x1, &y1);
    printf("座標A(%d, %d)\n\n", x1, y1);

    int x2, y2;
    printf("座標Bを入力してください。\n?, ?: ");
    scanf("%d, %d", &x2, &y2);
    printf("座標B(%d, %d)\n\n", x2, y2);

    int a, b, c;
    a = (x1 < x2) ? (x2 - x1) : (x1 - x2);
    b = (y1 < y2) ? (y2 - y1) : (y1 - y2);
    c = r1 + r2;
    printf("a=%d, b=%d, c=%d\n", a, b, c);

    // ピタゴラス(三平方)の定理
    // a^2 + b^2 = c^2
    if (c*c >= a*a + b*b) { // 斜辺(c*c) が a*a+b*b 以下なら
        printf("%d >= %d + %d\n", c*c, a*a, b*b);
        puts("衝突しています。");
    } else {
        printf("%d < %d + %d\n", c*c, a*a, b*b);
        puts("衝突してません。");
    }

    return;
}
[root@dev-c2]# ./a.out
座標A(?, ?), 座標B(?, ?) を中心とする、
円A(半径=2), 円B(半径=3) が衝突しているか判断します。

座標Aを入力してください。
?, ?: 3, 2
座標A(3, 2)

座標Bを入力してください。
?, ?: 6, 4
座標B(6, 4)

a=3, b=2, c=5
25 >= 9 + 4
衝突しています。
[root@dev-c2]# ./a.out
座標A(?, ?), 座標B(?, ?) を中心とする、
円A(半径=2), 円B(半径=3) が衝突しているか判断します。

座標Aを入力してください。
?, ?: 3, 2
座標A(3, 2)

座標Bを入力してください。
?, ?: 7, 4
座標B(7, 4)

a=4, b=2, c=5
25 >= 16 + 4
衝突しています。
[root@dev-c2]# ./a.out
座標A(?, ?), 座標B(?, ?) を中心とする、
円A(半径=2), 円B(半径=3) が衝突しているか判断します。

座標Aを入力してください。
?, ?: 3, 2
座標A(3, 2)

座標Bを入力してください。
?, ?: 8, 4
座標B(8, 4)

a=5, b=2, c=5
25 < 25 + 4
衝突してません。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2019/06/11 05:04

    思った通り動かないからデバッグしてほしいだけでしょ。

    キャンセル

  • 退会済みユーザー

    2019/06/11 09:21

    複数のユーザーから「問題・課題が含まれていない質問」という意見がありました
    teratailでは、漠然とした興味から票を募るような質問や、意見の主張をすることを目的とした投稿は推奨していません。
    「編集」ボタンから編集を行い、質問の意図や解決したい課題を明確に記述していただくと回答が得られやすくなります。

回答 6

+3

こんにちは。

制限時間15分の試験で、C言語の衝突を判定するプログラムを
手書きで書いてください。

もし皆さんが、
同様の状況に置かれたとしたら、どんなコードを書きますか?

たぶん衝突判定をする関数だけ書きます。
そもそも入出力仕様が未定義ですから自由に解釈してよい筈です。また手書きなので動くことは期待されていないでしょう。更に余分なコードをかけば書くほど、単純バグの確率が高くなります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

きちんと私のほうでも動くの確認しました。
試験での出題内容がわからないから、何とも言えないけど、半径は固定で、座標が整数である円の衝突の判定のみを行うプログラムを書くなら同じように書いたと思う。
小さいプログラムであることと、試験の問題で、後々他に流用するわけではないことから、関数に分ける必要もないかと思う。

全く別の話になってしまうけど、rootでログインしていることが少し気になったくらい...

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/11 10:45 編集

    ほんとにきちんと動きますか?
    エラーが出ないというだけではありませんか?
    試験だとしたら、大勢の受験生のコードをいちいち人が見てチェックしていくのではなく、実行してその結果を正解と比べていくことで採点すると思いますが、このコードは正解を出さないはずです。

    キャンセル

  • 2019/06/11 12:33

    Zuishinさんこんにちは。コメントいただきありがとうございます。
    正解を出さないはずとはどのような場合のことでしょうか?
    予期しない値を代入すればエラーは発生するとは思いますが、それらの対処も書くべきということでしたらわかりますが、実行例のように、期待している値であれば、正常に動くと思います。

    キャンセル

0

a,bに関しては二乗するので絶対値を取る必要はないですね

あとは、テストの問題に入力値の明示がほしいところです
もし、x1=100000みたいな数値が入ってしまうと、
二乗したときにintの範囲をはみ出してしまうので一工夫必要です
なので、doubleを使って受けるほうが良いかもしれません

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/11 15:57 編集

    貴方、そこまで言うならJavaのBigDecimalクラスをC言語で実装しますか?
    見た感じ、C言語の初心者のテストだからこれでいいと思いますよ。
    そもそも入力値の型の指定はないのですし...

    キャンセル

  • 2019/06/11 17:37

    入力値が100億までとなっていると受け取る段階で32bitで足りないとわかりますが、10万だと32bitで足りるのでintで受けて事故るわけです
    この手の問題ではよく見るど定番の落とし穴だと思いますが…

    キャンセル

  • 2019/06/12 09:36 編集

    業務なら、その落とし穴までしっかりとサポート致しますが、この問題の出題者もそんなこと気にしていないと思いますよ。15分ではそのど定番の落とし穴を解決するには時間があまりにも足りない。

    そのど定番の落とし穴のプログラムをすべて暗記しろなんて酷なことですし、その上記入方法が手書きなので気にしなくてもいいかと思います。
    Chironianさんも仰っていますが、更に余分なコードをかけば書くほど、単純バグの確率が高くなります。

    キャンセル

  • 2019/06/12 11:11

    余計なコードって言ってますけど、私の提案はintの部分をdoubleに書き換えるだけですよ?
    それに合わせてscanfも修正しますけど、バグ混入レベルには程遠いかと
    学校のテストならOKでも企業の入社テストならこういう細かい部分で加点対象になるし、知っておくべき知識でしょう

    キャンセル

  • 2019/06/12 11:35

    私はつい2進の計算誤差問題とか「100億」「10万」と直接入力されたら場合の問題とかまで考慮するのかと...
    すみません、その程度なら変更した方が良いでしょうね。

    キャンセル

0

A円に属する x1,y1,r1 / B円に属する x2,y2,r2 は, 接尾 1/2 ではなく 接頭 a/b にします.
a, b の計算は abs() を使います.
入力2回が同じなので関数化するかもしれませんが, そうすると(関数化しない)出力とバランスが悪く感じるので, そのままかもしれません.

なお, 結果に関しては確認しておりません.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

-1

出題の雰囲気(?)次第なのかもしれませんが……
その言われ方そのままだとしたら,
主題である「判定する」部分だけを関数として書くと思います.
そして,該関数の入出力に関する注釈をしっかり書きます.

仮に,その他の部分まで含めて書く必要があるのだとしても,
提示コードのようにmain関数内に全部突っ込むという書き方にはしないと思います.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/11 16:44

    低評価GET!
    できれば,理由などコメントいただけると嬉しいです!

    キャンセル

  • 2019/06/13 13:36

    このサイトで何か書くとたまに高なり低なりの評価をいただけるんだけど,
    多くの場合その理由を書いてくれないのが残念なところ.
    特に低評価側の理由(例えば間違いの指摘とか)が得られればためになるのだけど.

    キャンセル

-2

制限時間15分の試験で、C言語の衝突を判定するプログラムを
手書きで書いてください。
もし皆さんが、
同様の状況に置かれたとしたら、どんなコードを書きますか?

15分という制限時間の中で書くの「仕様通りに動けばよかろう」理論でいいと思います。
つまりそのままで良い。しっかりと書いている思います。

printf("座標A(?, ?), 座標B(?, ?) を中心とする、\n");
printf("円A(半径=%d), 円B(半径=%d) が衝突しているか判断します。\n\n", r1, r2);
printf("座標Aを入力してください。\n?, ?: ");
printf("座標Bを入力してください。\n?, ?: ");

私ならここは絶対に書きません。なんせ15分という短い時間で終わらせなければならないのだから...
時間が余ったら書くぐらいでいいと思います。

しかし、開発なら流用性や利便性を考え、まずベクトルの構造体と長さを取得する関数を制作した後に、さまざまな衝突判定の関数を作ります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • C

    4641questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • トップ
  • Cに関する質問
  • C言語で衝突を判定するプログラムを書きましたが、もっと分かりやすく書けますか。