教えて!gooにおける不適切な投稿への対応について

C++で(v1=)(1,2,3)×(3,2,1)(=v2)の外積を計算したいのですが、画像のように入力すると(3,0,0)となり正しく実行されませんでした。内積は正しく実行されているので、外積のプログラム内で誤りがあるはずなのですが、どこが不適かご教示ください。正確な値は(-4,8,-4)です。

「C++で外積」の質問画像
gooドクター

A 回答 (3件)

惜しいなぁ。

ミスのせいですねぇ。
殆どケアレスミスの範疇です。

まずはプロトタイプのここ、から。

> double op(double v1[], double v2[], double v3[]);

ここ、あとで発覚するんだけど、発想的には「配列自体を返したい」わけでしょ?
そうすると、double型が返り値になる、って指定はマズいです(何故ならdoubleは単なる数値だから)。ここはdouble型のポインタを返すのが正解。
つまり、

double* op(double v1[], double v2[], double v3[]);

にしないといけません。

> int i;

main内では変数iは使われてないので要りません。

> printf(" outer product = (%f, %f, %f)\n", op(v1, v2, v3));

ここがウッカリさん。
op(v1, v2, v3)が配列を返すのだったら、printfの書式設定(ここでは(%f, %f, %f)とされている)、は残念ながら配列をアンパックして表示する、なんつー、気の利いた機能は持ってないのです。
何故ならC/C++はかなりアホだから、です。
それより、opと言う関数はv3を破壊的に変更する、って性質を持ってるので、このprintfの前でopを呼んでv3を書き換えちゃうのが正解です。何故ならopを呼んだ時点でv3には既に答えが入ってる。
従って、ここは二行にして、

op(v1, v2, v3);
printf(" outer product = (%f, %f, %f)\n", v3[0], v3[1], v3[2]);

とするのが正解です。

あとは、

double* op(double v1[3], double v2[3], double v3[3]) // 返り値はdoubleのポインタ型
{
// double v3は要らない。引数に与えられている
 v3[0] = v1[1] * v2[2] - v1[2] * v2[1];
 v3[1] = v1[2] * v2[0] - v1[0] * v2[2];
 v3[2] = v1[0]*v2[1] - v1[1] * v2[0];
 return v3; // 名前を返すだけで良い。
}

以上、ですね。
    • good
    • 1
この回答へのお礼

回答ありがとうございます!
プログラムの修正だけでなく、部分部分の意味も丁寧にご教示いただき感謝申し上げます。

お礼日時:2020/10/17 14:32

まったく本題とは関係ないけど v3[3] を返すのは (意味的に) まずい, と認識できるようになるといいなぁ.

    • good
    • 0
この回答へのお礼

回答ありがとうございます。
基礎知識が抜けている感じですね。丁寧に勉強します。

お礼日時:2020/10/17 14:33

外積の関数の定義を、



void op(double v1[], double v2[], double v3[]);

ってした方が良いかも。
外積は、v3の配列に格納されるのでは。

あと、warningが出てるハズなので、しっかり潰す。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
参考にさせていただきます!

お礼日時:2020/10/17 14:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

gooドクター

このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング