次の 2 つの関数を検討します。
int foo(int, int);
と
int bar(int*);
(bar がサイズ n の配列で渡され、n = foo パラメーターの数であると仮定すると、それぞれの値は同等であり、関数は機能的に同じです)
後者よりも前者のアプローチを取る方が「良い」のでしょうか?
次の 2 つの関数を検討します。
int foo(int, int);
と
int bar(int*);
(bar がサイズ n の配列で渡され、n = foo パラメーターの数であると仮定すると、それぞれの値は同等であり、関数は機能的に同じです)
後者よりも前者のアプローチを取る方が「良い」のでしょうか?
これは、「より良い」とはどういう意味かによって異なります。複数のパラメーターを渡す方がプログラムの論理構造とより適切に一致している場合は、読みやすさのために複数のパラメーターを渡す方が間違いなくはるかに優れています。これが当てはまるかどうかの良いテストは、配列の個々の要素に個別に名前を付けることでメリットがあるかどうかを尋ねることです。答えが「はい」の場合は、個々のパラメーターの方が適しています。パラメータを渡すときにあちこちで数バイトを節約しても、読みやすさのわずかな低下を補うことはできません。
はい、前者のアプローチint foo(int, int);
では、コンパイル時にパラメーターをチェックできます。int bar(int*)
渡された配列について仮定する必要があります。
私が考えることができる1つの欠点int bar(int*)
は、オーバーロードがより困難になる可能性があることです。例えば:
int areaOfRectangle(int width, int height);
int areaOfRectangle(int x1, int y1, int x2, int y2);
大丈夫ですが、配列でそれをどのように行うのですか?
int areaOfRectangle(int* widthHeight);
int areaOfRectangle(int* coordinates); // error
上記はint areaOfRectangle(int*)
2回宣言/定義できないため、コンパイルされません。
また、パラメータを任意にグループ化する方法として配列を使用しているだけの場合は、コードを読みにくく、使用しにくくします。比較:
int calculateIncome(int normalHours,
int overtimeHours,
int normalRate
int overtimeRate); // Self documenting
int calculateIncome(int* parameters); // How do I use this function?
int calculateMean(int* numbers); // Parameters are logically grouped,
// so array makes sense
3番目の問題(サンチョが彼の答えで説明している)はそれint bar(int*)
が危険であるということです。ユーザーがあなたの関数をあなたが期待していたものよりも小さい配列と呼ぶとどうなりますか?int Foo(int, int)
一方、パラメータの数が間違っているへの呼び出しはコンパイルされません。
「より良い」とは何かによって異なります。
パフォーマンスを向上させるには:
1配列に少数の要素しかない場合(たとえば、6つ未満のパラメーター、ターゲットCPUに依存し、パラメーターを渡すために使用できるレジスターを使用できる場合)、すべての変数をレジスターで渡すことができるため、foo()メソッドの方が優れています。foo はレジスタから値を直接取得できます。バーの場合、ポインターの逆参照が必要です。
2 配列に 10 を超える項目がある場合。スタックの一番上にパラメーターをプッシュするためのスタック操作が少ないため、ポインターを使用して渡すことをお勧めします。
バグが少ない場合: foo() メソッドの方が優れています. bar() 内の項目の操作には注意してください。