機能f
が配列し、その配列のサイズを取得し、再帰的に近隣の値を比較し、最終的に戻って隣接する値間の最大距離(数値、非絶対)。あなたの場合、関数は3
を返します。これは、5
と2
の間の最大距離3を表します。この場合の2
と6
の差は、絶対値がとられていないので、-4
です。
f(p+1,n-1)
には2種類の演算があるため、再帰的なケースは少し混乱します。 p+1
はポインタの演算であり、n-1
は通常の数値演算です。 p+1
は配列ポインタを次の要素に進めているだけで、n-1
は配列サイズをデクリメントしているため、比較する要素がなくなったときに関数が終了します。
ベースケースでは、すべてのペアを既にチェックしている場合、最高距離はゼロであると言われています。
計装コード
次のコードは、max()
使用を除去し、最大の差を計算するための単純な三元表現を選ぶなど、インストルメントされます。機能的には、これは投稿されたものと同じでなければなりませんが、機能にはprintf
と、アドレスにはmain()
が追加されています。それは上記のことを増幅するはずです。
#include <stdio.h>
int f(int *p, int n)
{
// no sense in checking zero or one element.
if (n <= 1)
return 0; // actually, this should be INT_MIN, but whatever
// print this call-frame for the values we're interested in
printf("p = %p, n = %d, p[0] = %d, p[1] = %d\n",
(const void*)p, n, p[0], p[1]);
int lhs = f(p+1,n-1); // recurse here
int rhs = p[0] - p[1];
// return the maximum of the two values
return (lhs < rhs) ? rhs : lhs;
}
int main()
{
int a[] = {3,5,2,6,4};
printf("%p %d", (const void*)a, f(a,5));
}
出力(注:アドレスは、システムによって異なります)最後の行は、main()
でa[]
のベースアドレスを示すこと
p = 0x7fff5fbff970, n = 5, p[0] = 3, p[1] = 5
p = 0x7fff5fbff974, n = 4, p[0] = 5, p[1] = 2
p = 0x7fff5fbff978, n = 3, p[0] = 2, p[1] = 6
p = 0x7fff5fbff97c, n = 2, p[0] = 6, p[1] = 4
0x7fff5fbff970 3
注意。関数の最初の呼び出し(上の行)は、同じアドレスを示しています。先に説明したポインタの算術に基づいてアドレスがどのように調整されるかに注意してください。 n
の値の減少と相まって、それぞれの再帰呼び出しは「より短い」シーケンスになります。実際には同じシーケンスです。異なる位置から開始し、異なる要素数で開始します。
これだけです。
あなたの質問は何ですか? –
@ RobertColumbia、私はこの行を取る再帰を理解していませんmax(f(p + 1、n-1)、p [0] -p [1]) – sagg1295
それをデバッガで実行し、ネストされた呼び出しにステップします。あるいは、そこにいくつかの 'printf'を振りかけるだけで、それがどこにあるのか見ることができます。 – WhozCraig