【C言語】最大値と最小値を求める方法

C言語における最大値と最小値の求め方の解説ページアイキャッチ

このページにはプロモーションが含まれています

このページでは、C言語で複数の値から「最大値・最小値」を求める方法について解説していきます。

C言語では、他の言語とは異なり、maxmin といった最大値・最小値を求める関数が標準では用意されていません。

処理系によっては用意されている場合があるようですが、用意されていない場合は自身で最大値や最小値を求める必要があります(私は MacOSX を使用していますが、maxmin は用意されていないようでした)。

ただ、最大値や最小値を求めるのは簡単なので、自身で求めるとしてもそこまで負担にはならないと思います。

ということで、このページでは最大値や最小値を求める方法について解説していきます。

2つの値の最大値を求める

最大値や最小値を求める上で一番基本になるのは、この「2つの値から最大値を求める」処理になると思います。

ただ、求め方は単純で、2つの値を比較演算子で比較して「大きい方の値」を最大値としてやれば良いだけです。

2つの値の最大値を求める関数

例えば下記は、2つの値の最大値を求める関数の例となります。

2つの値の最大値を求める関数
int maxValue(int num1, int num2) {
    int max_value; /* 最大値 */

    /* 2つの値を比較して大きい方を最大値とする */
    if (num1 > num2) {
        max_value = num1;
    } else {
        max_value = num2;
    }

    return max_value;
}

上記では2つの引数 num1num2 の比較を行って大きい方の値を max_value に格納し、その max_value を最大値として返却するようにしています。

もし2つの値が同じである場合、どちらの値を最大値として選んだとしても結果は同じになります。

上記では num1 == num2 の場合に num2 が最大値となるようにしていますが、num1 > num2 の部分を num1 >= num2 に変更すれば、num1 == num2 の場合に num1 が最大値となるようになります。

ただし、前述のように両方同じ値なのですから、いずれにしても正しく最大値を求めることができます。

スポンサーリンク

2つの値の最大値を求める関数(float

上記の maxValue 関数は int 型の2つの値から最大値を求める関数の例となります。

当然最大値は他の型の値でも求めることが可能であり、上記の maxValue 関数も型さえ変更してやれば “他の型の2つの値から最大値を求める関数” に変更することが可能です。

例えば float 型の2つの値から最大値を求める関数は、次のように上記の maxValue 関数の “返却値の型” と “比較対象となる引数の型” および “最大値を扱う変数の型” を float に変更するだけで実現することができます。

2つの浮動小数点数の最大値を求める関数
float maxValue(float num1, float num2) {
    float max_value; /* 最大値 */

    /* 2つの値を比較して大きい方を最大値とする */
    if (num1 > num2) {
        max_value = num1;
    } else {
        max_value = num2;
    }

    return max_value;
}

以降で紹介する関数についても同様ですので、最大値を求めたい値の型に応じて適宜変更していただければと思います。

2つの値の最大値を求める関数(3項演算子)

また、最初にお見せした maxValue 関数は3項演算子を利用すれば下記のように簡潔に表すことも可能です。

2つの最大値を求める関数(3項演算子)
int maxValue(int num1, int num2) {
    return (num1 > num2) ? num1 : num2;
}

2つの値の最小値を求める

最大値を求める時とは逆に、最小値を求める際には2つの値を比較して「小さい方の値」を最小値として返却するようにします。

2つの値の最小値を求める関数
int minValue(int num1, int num2) {
    int min_value; /* 最小値 */

    /* 2つの値を比較して小さい方を最小値とする */
    if (num1 < num2) {
        min_value = num1;
    } else {
        min_value = num2;
    }

    return min_value;
}

関数名や変数名、さらにはコメントは異なるものの、2つの値の最大値を求める の最初で紹介した maxValue 関数と実質的に処理が異なるのは「比較実行部分のみ」です

具体的には、maxValue 関数で比較演算子に > を使用していたところを maxValue 関数では < を使用するように変更しただけです。

つまり、最小値を求める関数やプログラムは、最大値を求める関数やプログラムから “比較演算子を変更さえすれば実現可能” ということです。

これは2つの値から最大値・最小値を求める時に限った話ではなく、以降で解説する「配列の中から最大値を求める」場合においても同様です。ですので、説明の重複を避けるため、今後は最大値に関する解説のみを行うものとさせていただきます。

最小値を求めたい場合は、紹介する関数で使用している比較演算子を > から < に変更してください(>= を使用している箇所は <= に変更してください)。これにより、最小値を求める関数を実現することが出来ます。

スポンサーリンク

配列の中から最大値を求める

次は配列の中から最大値を求めていきたいと思います!

配列の中から最大値を求める関数

C言語においては、3つ以上の値を同時に比較することはできません。

そのため、ループ処理の中で、その時点の最大値と配列の要素の値を1つ1つ比較をしていく必要があります。

具体的には、下記の関数 maxValue により、サイズ n の配列 nums の全要素から最大値を求めることができます。

配列の中から最大値を求める関数
int maxValue(int nums[], int n) {
    int max_value; /* 最大値 */
    int i;

    /* nums[0]を最大値と仮定する */
    max_value = nums[0];

    for (i = 0; i < n; i++) {
        if (nums[i] > max_value) {
            /* 最大値よりもnums[i]の方が大きければ最大値を更新 */
            max_value = nums[i];
        }
    }

    return max_value;
}

n0 以下の場合はうまく動作しないので注意してください(配列外にアクセスしてしまう)。

maxValue 関数でやってる処理は簡単で、配列の先頭の値が最大値であると仮定し、その最大値よりも大きい値を見つける度に最大値を更新していくことで最大値を求めています。

具体的には、まず配列の先頭の値が最大値であると仮定し、max_value = nums[0] を行なっています。この max_value は最大値を格納するための変数になります。

配列の中から最大値を求める手順1

以降は、ループ処理の中で配列の先頭から各要素の値 nums[i]max_value の比較を行い、nums[i]max_value よりも大きな値であった場合、max_value は最大値ではなかったということになりますので、max_value = nums[i] を行なって最大値を nums[i] に更新します。 

配列の中から最大値を求める手順2

もちろん、nums[i]max_value 以下の値の場合は max_value が最大値である仮定は崩れていないので、max_value の更新を行う必要はありません。

配列の中から最大値を求める手順3

あとは上記のように max_value よりも大きな値を見つけるたびに max_value の更新を行っていけば、配列の末尾まで同様の処理が完了したタイミングで max_value には配列全体の中の最大値が格納されていることになります。

配列の中から最大値を求める手順4

これにより配列 nums の中の最大値 max_value が求まったことになります。

ちなみに、maxValue 関数の for ループでは i0 から開始していますが、i が 0 の場合は nums[i] > max_value は絶対に成立しないことが分かりきっているため、i は 1 から開始するのでも問題ありませんん。

また、上記の maxValue 関数内で使用している比較演算子 >>= に変更したとしても、最大値は正しく求めることが出来ます。

ですので、単に最大値を求めたいのであればどちらの比較演算子を使用しても問題ありません。

ただ、下記ページのように「最大値の持つ要素の添字」を求める際には、どちらの比較演算子を用いるかによって結果が異なることになるので注意してください。

C言語での配列の中の最大値を持つ要素の添字を求める方法の解説ページアイキャッチ 【C言語】配列の中から最大値を持つ要素の”添字”を求める

配列の中から最大値を求める際の注意点

前述で説明した for ループ内の処理自体は単純だと思いますが、下記の処理を忘れないように注意が必要です。

最大値の仮定
/* nums[0]を最大値と仮定する */
max_value = nums[0];

不定値との比較を行わないように注意

for ループの先頭で max_valuenums[i] の比較を行なっているので、for ループに入る前に max_value に何らかの値を代入しておく必要があります。

代入を忘れると max_value に「不定値」が格納された状態で比較が行われてしまうので、不定値の値によっては上手く最大値が求められなくなってしまいます。

配列の中の最大値以下の値を代入しておく必要あり

具体的に、max_value に代入しておく必要のある値は「配列 nums の最大値以下の値」となります。

例えば下の図の配列において、max_value = 53 としてから for ループを実行しても一度も max_value が更新されず、配列内に存在しない 53 が最大値 max_value として返却されてしまいます(逆に max_value52 以下とした場合、正しく最大値が求められることも確認できると思います)。

max_valueの初期値によっては最大値が正しく求められない例

このようなことにならないように、max_value には「確実に配列 nums の最大値以下である」と言える値を代入しておく必要があります。

配列の中の最大値以下の値とは

で、「確実に配列 nums の最大値以下である」と言える値が、配列 nums の要素のいずれかとなります。配列 nums の最大値を超える値が配列 nums の要素の中にあったらおかしいですよね。

確実に配列の最大値よりも小さくなる値の説明図

ですので、for ループに入る前に max_value に nums の要素のいずれかを代入しておけば、max_value は「確実に配列 nums の最大値以下である」と言える値となり、上手く最大値を求めることができるようになります。

上記の関数では nums[0] を代入していますが、nums[0]nums[n - 1] のどれを代入しても上手く最大値を求めることができます。ただ、配列の先頭 or 末尾の値を代入しておく方が、ソースコードとしては分かりやすいとは思います。

もちろん max_value には「確実に配列 nums の最大値以下である」と言える値であれば他の値を代入しておくのでも良いです。

例えば配列内に正の値しか格納されていないことが保証できるのであれば、max_value0 や負の値を代入しておくのでもオーケーです。

ただ、その辺りを考慮するくらいであれば、素直に配列のいずれかの値を代入する方が楽かなぁとは思います。

ちなみに、ここまでの話は「単なる最大値」を求める場合の話であって、下記ページのように「最大値の持つ要素の添字」を求める際には、max_value に設定する値をもっとしっかり考慮して決める必要があります。

C言語での配列の中の最大値を持つ要素の添字を求める方法の解説ページアイキャッチ 【C言語】配列の中から最大値を持つ要素の”添字”を求める

スポンサーリンク

まとめ

このページでは、C言語での「最大値・最小値」の求め方について解説しました!

2つの値から最大値を求める際には、単に2つの値の比較を行い、大きい方を最大値としてやれば良いだけです。また最小値に関しては、最大値を求めるときと比較演算子を逆にしてやることで求めることが出来ます。

配列の中から最大値を求める際にも基本は2つの値の比較の繰り返しを行えば良いだけですが、最大値よりも大きな値を見つけた際に最大値を更新する必要があるので注意してください。

また、繰り返し処理を行う前には仮の最大値の設定を行う必要がある点にも注意してください。仮の最大値としては「配列の要素のいずれかの値」とするのが楽だと思います。

最大値や最小値を求める処理は度々必要になりますので、関数や関数マクロとして用意しておくと便利だと思います!

単に最大値を求めるのではなく、「配列の中の最大値を持つ要素の添字」を求めたくなる事もよくあります。この方法に関しては下記ページで解説していますので、是非こちらのページも続けて読んでみてください!

C言語での配列の中の最大値を持つ要素の添字を求める方法の解説ページアイキャッチ 【C言語】配列の中から最大値を持つ要素の”添字”を求める

オススメの参考書(PR)

C言語学習中だけど分からないことが多くて挫折しそう...という方には、下記の「スッキリわかるC言語入門」がオススメです!

まず学習を進める上で、参考書は2冊持っておくことをオススメします。この理由は下記の2つです。

  • 参考書によって、解説の仕方は異なる
  • 読み手によって、理解しやすい解説の仕方は異なる

ある人の説明聞いても理解できなかったけど、他の人からちょっと違った観点での説明を聞いて「あー、そういうことね!」って簡単に理解できた経験をお持ちの方も多いのではないでしょうか?

それと同じで、1冊の参考書を読んで理解できない事も、他の参考書とは異なる内容の解説を読むことで理解できる可能性があります。

なので、参考書は2冊持っておいた方が学習時に挫折しにくいというのが私の考えです。

特に上記の「スッキリわかるC言語入門」は、他の参考書とは違った切り口での解説が豊富で、他の参考書で理解できなかった内容に対して違った観点での解説を読むことができ、オススメです。題名の通り「なぜそうなるのか?」がスッキリ理解できるような解説内容にもなっており、C言語入門書としてもかなり分かりやすい参考書だと思います。

もちろんネット等でも色んな観点からの解説を読むことが出来ますので、分からない点は別の人・別の参考書の解説を読んで解決していきましょう!もちろん私のサイトも参考にしていただけると嬉しいです!

入門用のオススメ参考書は下記ページでも紹介していますので、こちらも是非参考にしていただければと思います。

https://daeudaeu.com/c_reference_book/

同じカテゴリのページ一覧を表示