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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1303閲覧

C++でのVector配列の先頭ポインタについて

9zou

総合スコア14

C

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/04/14 07:32

前提・実現したいこと

引数で指定された数までの過剰数を求めるプログラムの実装を別ファイルに書き、実行ファイル側にそのプログラムの使用と出力の実装を行ったところ、実行結果が何かおかしいので、質問しました。
これは、何が起きてこうなっているのかを教えていただきたいです。
よろしくお願いいたします。

発生している問題・エラーメッセージ

8978624 9006664 18 20 24 28 30 36 40 42 48 54 56 60 66 70 72 78 80 84 88 90 96 100

実行結果です。
最初の2つ以外はあっているのですが、最初の2つが明らかにおかしい数字になっていて、どうしたことかと途方に暮れております。

該当のソースコード

myMath.cpp

C++

1#include "myMath.h" 2#include <vector> 3 4int* AbundantNumber(int num) { 5 int sum = 0; 6 std::vector<int> ans; 7 for (int i = 1; i <= num; ++i) { 8 if (IsAbundantNumber(i)) { 9 ans.emplace_back(i); 10 } 11 } 12 ans.emplace_back(-1); 13 14 return &ans.front(); 15} 16 17bool IsAbundantNumber(int num) { 18 int sum = 0; 19 for (int i = 1; i <= num; ++i) { 20 if (num % i == 0) { 21 sum += i; 22 } 23 } 24 25 return (sum >= num * 2); 26}

main.cpp

C++

1#include "myMath.h" 2#include <iostream> 3using namespace std; 4 5void Show(const int* arr) { 6 for (int i = 0; arr[i] != -1; ++i) { 7 cout << arr[i] << " "; 8 } 9 cout << endl; 10} 11 12int main(void) { 13 14 Show(AbundantNumber(100)); 15 16 return 0; 17} 18

試したこと

色々試しましたが、vectorをそのまま渡す方法でしか解決できそうになかったです。。。

補足情報(FW/ツールのバージョンなど)

Windows g++(MinGW.org GCC-6.3.0-1)6.3.0

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

どうも-1を終端マーカーに使う戦略のようですが、std::vectorの良さを殺していて実行速度的にも非効率的と言わざるを得ません。

せっかくstd::vectorはメンバ関数size()を持つので、-1を終端マーカーに使うのはやめ(=AbundantNumberans.emplace_back(-1);しない,Showのループ条件をarr[i] != -1にしない)、素直にAbundantNumberstd::vectorを返却し、Showstd::vectorへのconst lvalue referenceを受け取るべきです。

cpp

1std::vector<int> AbundantNumber(int num) { 2 std::vector<int> ans; 3 for (int i = 1; i <= num; ++i) { 4 if (IsAbundantNumber(i)) { 5 ans.emplace_back(i); 6 } 7 } 8 return ans; 9} 10void Show(const std::vector<int>& arr) { 11 for (auto&& e : arr) { 12 std::cout << e << ' '; 13 } 14 std::cout << std::endl; 15}

投稿2019/04/16 06:34

yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2019/04/16 10:53

うん、素直/愚直に std::vector 返すのがオススメ。
9zou

2019/04/16 17:07

返信遅れまして、申し訳ございません!! やはり、それが一番スマートですよね、、、 ありがとうございます。
guest

0

C++

1int* AbundantNumber(int num) { 2 int sum = 0; 3 std::vector<int> ans; // ansはローカル変数だから 4 for (int i = 1; i <= num; ++i) { 5 if (IsAbundantNumber(i)) { 6 ans.emplace_back(i); 7 } 8 } 9 ans.emplace_back(-1); 10 11 return &ans.front(); // return直前にansが廃棄され、結果&ans.front() はゴミとなる。 12}

なので解決策としては static std::vector<int> ans; しといて、
呼ばれるたびに ans.clear(); でどうじゃろ。
※ マルチスレッドだとアレだけど。

[別解]

C++

1template<typename OutputIterator> 2OutputIterator AbundantNumber(int num, OutputIterator out) { 3 for (int i = 1; i <= num; ++i) { 4 if (IsAbundantNumber(i)) { 5 *out++ = i; 6 } 7 } 8 return out; 9} 10 11// call側はたとえば: 12 std::vector<int> result; 13 AbundantNumber(5, std::back_inserter(result)); 14 // 結果は resultに入ってる。

投稿2019/04/14 07:37

編集2019/04/17 09:23
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

9zou

2019/04/16 17:09

返信遅れまして、申し訳ございません! 当方vectorなどコンテナで返すのはあまり良くないことだと思っていたのですが、 間違っていたみたいです! やっぱり素直にvectorで返すことにします!!
episteme

2019/04/16 18:09

呼び側が受け皿を用意する手もあるけどね
9zou

2019/04/17 06:26

あまり考えが及ばなくてすみません、それはAbundantNumberの引数に出力したい配列を指定してあげるってことですか?
episteme

2019/04/17 10:25 編集

追記した。スタバにマイカップ持ってって「こいつに入れてください」ってゆーイメージ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問