ここから本文です

C言語の問題です。

アバター

ID非公開さん

2018/12/3016:23:58

C言語の問題です。

3個の整数を入力して最大値を求める問題なのですが、

#include <stdio.h>
main()

scanf("%d",&a);
scanf("%d",&b);
scanf("%d",&c);
省略
return(0);


のようにscanfを3回使ったら、もっと整数が増えた場合に面倒くさいな…と思いました。
10個、100個、それ以上の整数でも簡単に最大値を求める事の出来るプログラムの組み方を知りたいです!また初心者なので、何故そのようなプログラムを作ったのか等も説明して下さると嬉しいです。

補足{とscanfの間に、
int a,b,c;
を追加します、ご指摘して下さった方、ありがとうございます!

閲覧数:
126
回答数:
5

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

n2q********さん

2018/12/3017:39:41

~プログラム例~

#include <stdio.h>
int main()
{
int a[100], *p = a;
while (scanf("%d", p) == 1) {
if (++p == (&a)[1])
break;
}
if (p > a) {
const int* const end = p;
p = a;
int max = *p++;
while (p < end) {
if (max < *p)
max = *p;
++p;
}
printf("最大値は %d です。\n", max);
}
return 0;
}


《解説》

「10個、100個、それ以上の整数」ということで、ここでは 100 個にしてみましたよ。1000 個にしたい場合は int a[100] のところを int a[1000] にするだけです。(10万個ぐらいまでは平気です。それ以上はやめておいた方が良いです。)


これは配列というものなのですけれども、a[0] ~ a[99] までの100を用意したい時は int a[100]; とすれば良いのです。


あと、ポインタも用意しました。a[0] の位置を p というポインタ変数で指し示しています。

なお、ポインタの中には整数データは入ってなくて、別の整数データを抱えた変数の場所が入ってます。


while 文では scanf を呼び出して、戻り値が 1 であることを確認しています。整数以外が入力されたとき、(たとえば英字とかです)、0 が返って来ます。EOF に到達した時(Windows であれば [Ctrl]+[Z]、Unix 系であれば [Ctrl]+[D] などの入力があった時)は EOF が返されます。いずれにしろ 1 ではない値となりますので、その時は while 文は終わりとなります。


while 文の中では if 文を使ってポインタ変数が指している位置が配列の終わりに到達しているかどうかを見ています。

まず、++p ということで、現時点での p の位置を次の位置に進めます。そしてその新しい位置が a 配列の終わり(というか、同じ配列がもう1個あったとしてその位置)かどうかを確認。もしそうならば break 文によって while 文を抜けます。


while が終わった後の if 文はポインタ変数 p が配列の先頭よりも先に位置しているかを見ています。これはつまり、最低でも1個以上の値が入力されたかどうかを調べてるのですよ。1個も入力されてない場合は最大値が幾らなのかは規定できないからです。


で、p > a が成立した場合は、新たなポインタとして end を用意して、現時点での p の位置を記憶させます。

そして p の方は a の先頭位置に設定しなおします。

最大値を表す max という変数を用意して、p が指す値(要は a[0] です)で初期化します。その後、p は +1 します。(これで p は a[1] の位置になります。)

while 文で、p が end の位置になるまで繰り返し。max よりも大きな値があれば、更新。p を次の位置に進める。


最終的に max に最大値が残りますのでこれを printf で出力して終わりとなります。

  • アバター

    質問者

    ID非公開さん

    2018/12/3017:44:10

    ご丁寧にありがとうございます!!
    すみません、私の理解力が乏しいが故に
    *pとpの違い?というのでしょうか、この2つは違うものなのかどうかが分かりません…すみません

  • その他の返信(3件)を表示

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

アバター

質問した人からのコメント

2019/1/3 22:10:36

1番私が理解出来た方のものをベストアンサーとさせて頂きますが、どの方のものも、全て自分の財産となりました。皆様、丁寧に答えて下さって、本当にありがとうございました!!

ベストアンサー以外の回答

1〜4件/4件中

並び替え:回答日時の
新しい順
|古い順

プロフィール画像

カテゴリマスター

ikt********さん

2018/12/3115:46:02

> ...のようにscanfを3回使ったら、もっと整数が増えた場合に面倒くさいな…と思いました。

その感覚は 健全 ですね、と思いました。
既にご回答あるように、
・繰り返し の制御構文
・配列 (だけではないですが...) といった高次のデータ構造
の学習を、するとよいです。


でも、qui********さん ご回答の視点、
重要ですよ。
求めたいのが 最大値だけ なのなら、
そもそも入力値全部をためこんで覚えておく必要、
ありませんから。


回答じゃない内容で、すみません。

nic********さん

2018/12/3023:07:10

最大値や中間値、最小値などの統計処理をするプログラムをC言語で作るのは大変なので Boost C++ Librariesの Accumulators というライブラリを使ってこんな風に書くことができます。

#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>

using namespace boost::accumulators;

int main()
{
accumulator_set<double, stats<tag::max> > acc;
int n;

for (int i = 0; i < 3; i++) {
std::cout << "数を入力";
std::cin >> n;
acc(n);
}

std::cout << "最大値は" << extract::max(acc) << std::endl;
}

たったこれだけで最大値を簡単に出せます。

数を入力50
数を入力20
数を入力25
最大値は50

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

プロフィール画像

カテゴリマスター

qui********さん

2018/12/3018:44:50

関係ない話ですが、k023uniqueさん、k032yfさんをご存知ではありませんか?
いや、ちょっと似てるような気がしたもので。

本題。

欲しいのは最大値だけですか?
ならば、必要なのは、
これまでの最大値と、
今回の入力値
だけですよね。今回の入力値が今までの最大値より小さければ今までの最大値が最大のまま、入力値が今までの最大値より大きければ、それが新しい最大値です。

ですから、
・scanfで何かの変数に値を得る
scanf("%d",&a);

・これまでの最大値と比較して入力値のほうが大きければ最大値を更新する
if(max<a){
max=a;
}

これをループのなかでくりかえせばいいわけです。

もちろん、maxの最初の値はどうしようとか、入力を終わりにする方法は、どうするかとか、考える必要はあるかも知れませんが。

k02********さん

2018/12/3016:39:04

1.
int a,b,c;
がないと、動かない。
コンパイルできるものを書く。

2.
問題を1個にする。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる