C 言語での MIN および MAX 関数

Ammar Ali 2023年10月12日
C 言語での MIN および MAX 関数

このチュートリアルでは、マクロまたはループを使用して、C 言語で MIN および MAX 関数を実装する方法について説明します。

C 言語の MIN および MAX 関数

MIN および MAX 関数は、2つの値から最小数と最大数を見つけるために使用され、C 言語では事前定義されていません。MIN および MAX 関数を使用する場合は、C 言語で定義する必要があります。

マクロを使用して、C 言語で MIN および MAX 関数を定義できます。マクロは、変数の値と関数を定義するために使用されるコードセグメントです。

マクロを呼び出すと、その値または関数に置き換えられます。たとえば、PI のような変数の値を定義できます。コードで PI という名前を使用すると、名前はその値に置き換えられます。

マクロを、その名前をコードに記述した場合に呼び出される関数として定義することもできます。 #define キーワードを使用して、C 言語でマクロを定義します。

たとえば、C 言語マクロを使用して MIN 関数と MAX 関数を定義しましょう。以下のコードを参照してください。

#include <stdio.h>
#define MIN(i, j) (((i) < (j)) ? (i) : (j))
#define MAX(i, j) (((i) > (j)) ? (i) : (j))
int main() {
  printf("Min = %d\n", MIN(0, 10));
  printf("Max = %d", MAX(0, 10));
  return 0;
}

出力:

Min = 0
Max = 10

上記のコードでは、? 記号は三項演算子であり、if-else ステートメントの代わりに使用されます。三項演算子の前の条件が true の場合、出力はコロン:の左側に等しくなり、条件が false の場合、出力はコロン:の右側に等しくなります。

上記のコードでは、入力が a+b のような式になる可能性があるため、角かっこを使用しました。角かっこを使用しないと、出力が変化します。三項演算子の代わりに if-else ステートメントを使用することもできます。

上記のコードは、関数内で式を渡すという二重評価の副作用の場合に問題を引き起こします。__typeof__ コマンドを使用して MIN および MAX 関数を定義し、上記の問題を回避して、安全性を高め、バグを減らすことができます。

__typeof__ コマンドは、式のタイプを参照します。typeof コマンドを式と型で使用できます。

たとえば、__typeof__ コマンドを使用して、上記の MIN および MAX 関数を定義しましょう。以下のコードを参照してください。

#include <stdio.h>
#define MAX(x, y)       \
  ({                    \
    typeof(x) _x = (x); \
    typeof(y) _y = (y); \
    _x > _y ? _x : _y;  \
  })

#define MIN(x, y)       \
  ({                    \
    typeof(x) _x = (x); \
    typeof(y) _y = (y); \
    _x < _y ? _x : _y;  \
  })
int main() {
  printf("Min = %d\n", MIN(0, 10));
  printf("Max = %d", MAX(0, 10));
  return 0;
}

出力:

Min = 0
Max = 10

上記のコードでは、__typeof__ コマンドを使用して入力のタイプを参照し、次に三項演算子を使用して if-else ステートメントを定義しました。出力は前の例と同じであることがわかります。

上記のマクロは引数を 1 回だけ評価するため、上記のコードは二重評価の問題を回避できます。上記のメソッドは、2つの整数入力の場合にのみ機能します。

数値の配列に存在する最小数と最大数を見つけたい場合、上記の方法では 2つの数値のみを比較しているため、上記の方法を使用することはできません。配列の場合、配列に存在する最小値または最大値を見つけるために、すべての要素を一緒に比較する必要があります。

配列の最初の要素を変数に格納してから、ループを使用してこの要素を配列の他の要素と比較できます。

最大数の場合、次の要素が配列に存在する次の要素よりも大きい場合、保存された要素が配列に存在する最大要素ではないことを意味し、保存された要素を次の要素に置き換えます保存された要素が配列に存在するすべての要素と比較されるまで、この手順を繰り返します。

最小数の場合、次の要素が保存された要素よりも小さい場合にのみ、保存された要素を次の要素に置き換え、保存された要素が配列に存在するすべての要素と比較されるまでこの手順を繰り返します。

#include <stdio.h>

int MAX(int My_array[], int len);
int MIN(int My_array[], int len);
int main() {
  int My_array[] = {6, 3, 15, 9, 10, 50, 99, 11};
  int len = sizeof(My_array) / sizeof(My_array[0]);
  int numMax = MAX(My_array, len);
  int numMin = MIN(My_array, len);
  printf("Max number = %d\n", numMax);
  printf("Min number = %d", numMin);
  return 0;
}

int MAX(int My_array[], int len) {
  int num = My_array[0];
  for (int i = 1; i < len; i++) {
    if (My_array[i] > num) {
      num = My_array[i];
    }
  }
  return num;
}

int MIN(int My_array[], int len) {
  int num = My_array[0];
  for (int i = 1; i < len; i++) {
    if (My_array[i] < num) {
      num = My_array[i];
    }
  }
  return num;
}

出力:

Max number = 99
Min number = 3

上記のコードでは、2つの入力引数を持つ MAX()MIN() の 2つの関数を作成しました。最初の引数は指定された配列で、2 番目の引数は配列の長さです。

sizeof() 関数を使用して配列全体のサイズを検索し、それを配列の最初の要素のサイズで割って、指定された配列の長さを取得しました。

MAX() および MIN() 関数内で、配列の最初の要素を変数に格納し、整数のときに停止するループを使用して、配列の他のすべての要素と比較しました。i は配列の長さに等しくなります。これは、ループが配列の最後に到達したことを意味します。

ループ内では、if ステートメントを使用して配列の次の要素を保存した値と比較し、次の要素が保存された要素よりも大きい場合はその値を置き換えました(MAX() の場合)。関数、および MIN() 関数では、次の要素が保存された要素よりも小さい場合に値を置き換えます。printf() 関数を使用して、MIN() および MAX() 関数によって返される値を出力しました。

上記のコードは整数データ型の配列に対してのみ機能しますが、float などの他のデータ型の場合は、上記のコードを変更して最小数と最大数を見つけることもできます。上記のコードでは、float データ型の配列の場合、int データ型を float に変更する必要があります。

たとえば、配列のデータ型は float になり、配列の最初の要素を格納するために使用される変数のデータ型も float になり、長さのデータ型は同じままになります。

著者: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook

関連記事 - C Function