- ベストアンサー
C++の複数戻り値について
質問の閲覧ありがとうございます。 C++をはじめたばかりで勉強中のみなのですが どうしてもうまくいかない壁にぶつかってしまったので 是非お力を貸していただきたく、質問させていただきました。 C++にて課題を出されていまして、それを実現するのに ある関数に対し引数を複数渡し、戻り値を複数得たいのですが 下記のようなコードで、(実際は戻り値、引数がもっと多くなる 想定なのでreturnでは足りないです) 単純に、mainのa2の引数を"参照渡し"としtestにて代入した文字列を mainで再度受け取る、といったことを試しているのですが、うまくいかず このような形では実現不可能なのでしょうか? (文字列の代入をstrcpyに、charの宣言時に要素数を指定したりせずに) #include<iostream> using namespace std; void test(char* a2); int main() { char a2; test(&a2); cout << a2 << endl; } void test(char* a2) { a2="TEST_MESSEAGE1"; } 素人丸出しな内容で申し訳ないですが、ネット上の色々なサンプル等 で試してみても、理解がうまく得られませんでした。。。 ポインタ等の理解が浅いのもあるのかと思いますが。 ぜひご教授よろしくお願いいたします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
C++の関数は、「単一の」結果しか(直接には)返すことができません。 ということなのですが、「課題」の意図に反しなければ、構造体を使うと、実質的には複数の結果を返すことができます。 strcut paramDef { char *a; }; struct paramDef test() { struct paramDef result; rsult.a = "TEST_MESSAGE1"; return a; }; int main() { strcut paramDef value = test(); std::cout << value.a << "\n"; return 0; } 本当に複数のデータがあれば、 struct inputDef { int input1; int input2; double input3; }; struct outputDef { double out1; double out2; char *out3; }; struct outputDef test(struct inpuDef invalue) { strcut outputDef result; result.ou1 = (invalue.input1 + invalue.input2) / invalue.input3; result.ou2 = (invalue.input1 - invalue.input2) / invalue.input3; if (result.out1 > result.out2) result.out3 = "Add is larger"; else resutl.out3 = "Add is not larger"; return result; } int main() { struct inputDef inp; inp.input1 = 3; inp.input2 = 4; inp.input3 = 0.2; struct outputDef res = test(inp); std::cout << res.out1 << ", " << res.out2 << ", " << res.out3 << "\n"; return 0; }
その他の回答 (5)
- n2201makita
- ベストアンサー率30% (8/26)
提出されたプログラムをコンパイルして、実行してみましょう。 結果は、画面に何も表示されません。 理由は、18行目でa2に何かを代入していますが、代入された結果がmainに渡っていないためです。 ちなみに、9行目をa2='A';にしてみると、画面にはAと表示されます。内容が変わっていない為です。 次に、18行目を参照に対する変更の*a2=に直してみます。 キャストを合わせてコンパイルエラーを取ると、*a2=(char)"TEST_MESSAGE"; ですが、文字列の先頭アドレスとなる数字(char*)型を、char型のa2に代入しています。 18行目の"TEST_MESSAGE"を(char*)型のa2に代入する為には、引数でのa2の宣言はchar**a2にしなければなりません。 16行目と5行目をchar** a2に直します。 11行目の関数の呼び出しで型エラーのコンパイルエラーが出ますので、 9行目のa2の宣言をchar *a2;にします。 なお、出来上がったプログラムはANo.1さんの通りになります。
お礼
詳しい解説ありがとうございます。 中々頭に入らず、先ほどから何度も読み直していましたので とても助かります。 ポインタと文字列の組み合わせを何度も実装して叩き込んで生きたいと思います。ありがとうございました。
- titokani
- ベストアンサー率19% (341/1726)
> char a2; a2は「文字型」ですから一文字しか入りません。なのに、 > a2="TEST_MESSEAGE1"; 「文字列」を返そうとしているわけですから、これでは返るはずもありません。
お礼
回答ありがとうございます。 char a2とchar* a2の違い、文字データと文字列の違い があまり理解できてなかったみたいです。 ただ漠然と文字列なら・・・といった形で宣言しているようじゃだめなのですね。考慮不足でした。 ありがとうございました。
- jacta
- ベストアンサー率26% (845/3158)
複数というのがいくつかによりますが、2つでよければ、std::pairを使うのもひとつの手です。 std::pair<int, double> test() のようにすれば、intとdoubleの値をreturnで返せます。 同じ型の値を複数返したいのであれば、std::vectorを使ってもよいでしょう。 バラバラの型の値を3つ以上返すのは面倒ですが、比較的最近の処理系であればstd::tr1::tupleを使えることも多いので、調べてみるとよいでしょう。
お礼
回答ありがとうございます。 回答者様のような実装で回避できるパターンもありそうです。 少し違った方向からも考えて見れそうな気がします。 少し調べてみたいと思います。 ありがとうございます。
- kmee
- ベストアンサー率55% (1857/3366)
C++で参照渡しするには2通りの方法があります。 ・ポインタを使う(厳密にはポインタの値渡し) 引数を&変数として呼び出し→関数内で *仮変数 として実体を操作 ・参照を使う 引数に変数をそのまま→関数内では仮変数をそのまま操作 #1さんの方法はポインタを使ったものです。 参照を使うとこうなります。 void test( char *&pp ); void main( void ) { char *p; test( p ); cout << p << endl; } void test( char *&pp ) { pp = "TEST_MESSEAGE1"; }
お礼
回答ありがとうございます。 ポインタと参照渡しは同様のものと認識していたのですが 細かくするとそうではないのですね。 文献によっては参照渡しを進めていないものもあるようで、 理解に時間がかかりそうです・・・。ありがとうございました。
- tsukasa-12r
- ベストアンサー率65% (358/549)
このやり方だとできませんね。 やるとすれば、 void test( char **pp ); void main( void ) { char *p; test( &p ); cout << p << endl; } void test( char **pp ) { *pp = "TEST_MESSEAGE1"; } のような感じになります。
お礼
回答ありがとうございます。 あの形での実現しようとするとこういった形になるのですね、 やはり、ポインタの理解度が浅いように認識しています。
お礼
VBを少しかじっていたので、複数の戻り値は少なくないものかと 思っていましたが、そういうわけでもないようですね。 構造体はこういうのがある程度しかまだ手をつけていませんでしたので 是非検討したいと思います。 分かりやすいサンプルありがとうございます。とても助かります。