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

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

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

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

Q&A

解決済

4回答

370閲覧

C++ ポインタ渡し、参照渡し

amareno

総合スコア20

C++

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

0グッド

0クリップ

投稿2018/10/03 03:36

編集2018/10/03 10:03

前提・実現したいこと

現在C++でポインタ演算を用いて配列の平均と最大数、最小数を求めるコードを書いております。
関数 void meanHighLow(int* array, int size, double &average, int &high, int &low)からのポインタの渡し方の理解が乏しいのでコードが最後まで書けずつまずいてしまいました。

該当のソースコード

C++

1#include <iostream> 2 3using namespace std; 4 5void meanHighLow(int* array, int size, double &average, int &high, int &low); 6 7int main() { 8 9 const int size = 5; 10 int num[size] = {1, 2, 3, 4, 5}; 11 double mean = 0; 12 int max = 0; 13 int min = 0; 14 15 meanHighLow(num, size, mean, max, min); 16 17 cout << "The average is " << mean << endl; 18 19 cout << "The high value is " << max << endl; 20 21 cout << "The low value is " << min << endl; 22 23 24 return 0; 25} 26 27void meanHighLow(int* array, int size, double &average, int &high, int &low) { 28 int count = 0, sum = 0; 29 30 int *ptr; 31 ptr = array; 32 33 for (int i = 0; i < size; i++) { 34 ptr++; 35 sum = sum + *(ptr + i); 36 count++; 37 } 38 39 average = sum / size; 40 41 high = array[0]; 42 low = array[0]; 43 44 for (int i = 1; i < size; i++) { 45 if(low > array[i]) 46 low = array[i]; 47 if (high < array[i]) 48 high = array[i]; 49 } 50}

/Users/jane/CLionProjects/pointerArithmetic/cmake-build-debug/pointerArithmetic

Process finished with exit code 11
上記が私のコードのアウトプットです。
空白しか表示されません。

これら
cout << "The average is " << mean << endl;

cout << "The high value is " << max << endl; cout << "The low value is " << min << endl;

がアウトプットに表示されないのは何故でしょうか。教えて頂けるとありがたいです。

試したこと

多くの国内や海外のウェブサイトでみて試行錯誤しながらコードを書いていますがつまずいてしまいました。

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

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

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

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

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

dice142

2018/10/03 03:50

どの部分でつまずいたのでしょうか?平均などの求め方?関数の呼び出し? 「どうコードを書くのか」は丸投げの質問になりえますが、「関数の呼び出しがわからない」など具体的にわからない部分を明記していただけると回答が付きやすいと思います。
dice142

2018/10/03 03:50

あと質問文の「meanHighLow」という関数はコードのどこにあるのでしょうか?
y_waiwai

2018/10/03 03:51

なにをしたいんでしょうか。コードでは意図が読めません
amareno

2018/10/03 06:30

配列の平均値、最大値、最小値の求め方は分かるのですが、それらの計算結果をmain関数に渡す方法を教えて頂きたいです。
guest

回答4

0

合計/最大値/最小値 はライブラリにまかせればいいよ。

C++

1#include <iostream> 2#include <algorithm> 3#include <tuple> 4#include <numeric> 5 6void meanHighLow(int* array, int size, double &average, int &high, int &low) { 7 average = std::accumulate(array, array+size, 0.0) / size; 8 auto minmax = std::minmax_element(array, array+size); 9 high = *minmax.second; 10 low = *minmax.first; 11} 12 13int main() { 14 int array[] = { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 }; 15 double average; 16 int high; 17 int low; 18 meanHighLow(array, 10, average, high, low); 19 std::cout << "avg. = " << average << std::endl; 20 std::cout << "max. = " << high << std::endl; 21 std::cout << "min. = " << low << std::endl; 22}

投稿2018/10/03 10:56

episteme

総合スコア16614

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

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

0

ベストアンサー

コードに関してはLouiS0616様が回答していらっしゃるので別視点から。

配列の平均値、最大値、最小値の求め方は分かるのですが、それらの計算結果をmain関数に渡す方法を教えて頂きたいです。

平均値、最大値、最小値それぞれ同じ関数で計算して取得するのは
汎用性もないのであまり良い方法ではないと思います。
コードの作りの観点からアドバイスをすれば

  • 受け取った配列から平均値を計算して返す関数
  • 受け取った配列から最大値を探して返す関数
  • 受け取った配列から最小値を探して返す関数

に分けて使用するのが良いかと思います。
そうすれば参照渡しで結果を求めるという処理を避けることができます。


[関数の呼び出しについて追記]

引数の数など間違えていると思うのですが、何がどう違うのか少し教えて頂けないでしょうか。

呼び出し部分と定義部分を左から順番に確認していけば違いは分かるかと思います。

呼び出し部分

C++

1/* main関数内の呼び出し部分 */ 2meanHighLow(num, mean, sizeof(num) / sizeof(num[0]), &max, &min);
データ型整数配列小数整数整数整数
変数名nummeansizeof(num) / sizeof(num[0])&max&min

関数の定義部分

C++

1/* 関数の定義部分 */ 2void meanHighLow(int* array, int size, double &average, int &high, int &low);

| データ型 | xxx | xxx | xxx | ... |
| :--: | -- | -- | -- |
| 変数名 | yyy | yyy | yyy | ... |

呼び出し部分を真似て埋めてみて違いを見つけてください。


[追記された質問を見て追記]

このコードをコンパイルするとアウトプットに何も表示されません。

こちらの環境では表示されました。
出力部がないプログラムをコンパイルしたまま実行したとか
そういう点を確認してみてください。
コンパイルエラーはないのですよね?

paiza.ioで確認してたのですが、segmentation faultが起きずに
そのまま処理が行われていたようです。

原因は以下の部分ですね。

C++

1for (int i = 0; i < size; i++) { 2 ptr++; 3 sum = sum + *(ptr + i); 4 count++; 5}

ptr++でポインタを移動した後に
*(ptr + i)で更に先のアドレスを参照してます。

投稿2018/10/03 07:18

編集2018/10/03 10:17
dice142

総合スコア5158

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

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

amareno

2018/10/03 07:30

ご回答ありがとうございます。 そのように関数を分けて使用したいのですが、問題文に、関数 void meanHighLow(int* array, int size, double &average, int &high, int &low)を使うように書かれています。なので参照渡しで結果を求めるという処理をしなければなりません。説明不足で大変申し訳ありません。
dice142

2018/10/03 07:36

なるほど、問題文として関数が定義されてたのですね。納得しました。
amareno

2018/10/03 07:54

ご理解ありがとうございます。 main関数内の関数の呼び出しの部分、 meanHighLow(num, mean, sizeof(num) / sizeof(num[0]), &max, &min); 引数の数など間違えていると思うのですが、何がどう違うのか少し教えて頂けないでしょうか。
dice142

2018/10/03 08:33

回答に追記しました。
amareno

2018/10/03 08:46

ご親切にありがとうございます。参考にしながら正解にたどり着きたいと思います。
amareno

2018/10/03 09:58

すいません。回答ありがとうございます。 もし勘違いさせてしまいましたらすいません。 コンパイルするとアウトプットに何も表示されません。と書きましたがコンパイルするとアウトプットに何も私が表示したいこれら cout << "The average is " << mean << endl; cout << "The high value is " << max << endl; cout << "The low value is " << min << endl; が表示されませんという意味です。 これが私のコードのアウトプットです。 /Users/jane/CLionProjects/pointerArithmetic/cmake-build-debug/pointerArithmetic Process finished with exit code 11 分かりにくくて申し訳ありません。
dice142

2018/10/03 10:18

すみません、質問の解釈は合っていたのですが、私の確認した環境による出力の違いでした。 回答に追記しました。
amareno

2018/10/03 10:31

おかげさまで問題解決いたしました。長い間辛抱強く質問に答えていただき、本当にありがとうございました。感謝致します。
dice142

2018/10/03 10:51

解決できたようで何よりですが、出力はちゃんと確認してくださいね。
amareno

2018/10/03 18:14

はい、cateyeさんの情報を元にコードを手直ししました。出力は大丈夫そうです。ありがとうございます。
guest

0

おかしな所はさておき・・・

計算結果をmain関数に渡す方法

参照で渡しているので、関数内で設定した値は呼び出し元でも有効です。

投稿2018/10/03 08:11

cateye

総合スコア6851

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

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

amareno

2018/10/03 09:23

有益な情報ありがとうございます。参考になります。
cateye

2018/10/03 10:47

解決してよかったですd^^ で、蛇足ですが「average = sum / size;」は修正されましたか? LouiS0616さんが仰っているように、int/intは整数にしかなりません。なので、「average = static_cast<double>(sum) / size;」のようにどちらかをdoubleにして演算して下さい。今回は平均が整数(3)に成るのでいいのですが、少数以下が出るような場合には変換しないと平均値が出ません。
amareno

2018/10/03 18:06

すいません。全く気づきませんでした。参考になります。ありがとうございます。
guest

0

全体的におかしなコードが多いです。

関数pointerArithmetic内

C

array = nullptr;

必要ない処理です。
せっかく受け取ったポインタ変数を、ヌルポインタで上書きしてしまっています。

C

int *ptr;
ptr = array;

必要ない処理です。
arrayの型がそもそも int * であるのに、同型の変数に代入する意味がありません。

C

array[i] = 2 * i;

不可解な処理です。
受け取った配列を書き直すことに何か意味があるのでしょうか?

#####不足している処理

  • 最大値と最小値を求める処理

配列の先頭要素を暫定的な最大値/最小値と見做し、一つずつ比較していきます。

  • 平均値を求める処理

合計を要素数で割れば良いです。
ただし、C言語では 整数/整数=整数 になることに注意してください。

  • 計算結果を変数に格納する処理

平均値/最大値/最小値をそれぞれ average/high/low に引き渡します。
参照渡しなので呼び出し元にも影響します。

関数main内

C

int num[size];

肝心の配列のナカミが無いです。
宣言時に初期化するなり、入力を得るなり、何か値を入れてください。

C

pointerArithmetic(num, size);

計算結果を受け取る変数を宣言し、実際に与えてやってください。

C

for(int i = 0; i < size; i++) {
cout << num[i] << endl;
}

配列の各要素を出力してどうするんです?


多くの国内や海外のウェブサイトでみて試行錯誤しながらコードを書いていますがつまずいてしまいました。

試行錯誤すること自体は良いことですが、どこか継ぎ接ぎな印象を受けます。
良く理解しないままに転記しているのなら、それはコピペと同じで何の意味も無いです。

サイトを参考にするにしても、一段階一段階理解するようにしてください。

投稿2018/10/03 03:52

編集2018/10/03 04:00
LouiS0616

総合スコア35660

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

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

amareno

2018/10/03 04:48

ご回答ありがとうございます。参考にして引き続きコードを書いていきます。
amareno

2018/10/03 06:24

関数内で[ ]を使わないで、ポインタ演算を使用するようにと言われているので int *ptr; ptr = array; を使ってsum = sum + *(ptr + i); を表記しました。説明不足で申し訳ありません。
LouiS0616

2018/10/03 07:39

*(array+i) でもできるはずですが
amareno

2018/10/03 07:59

すいません。おっしゃる通りです。気づかせてくだってありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問