Cでは次のように動作しますか?
struct fdBase *left, *right;
int result = (int)(left - right);
result
負になる可能性があります。それがうまくいかない場合、どのように書きますか?
私の目標は、ポインタのいわゆる「コンパレータ」である赤黒木ソート関数に提供するものを持つことです。私は配列作業を行っていません。ポインタ間の実際の差がバイト単位で必要です。
C での 2 つのポインターの減算の結果は、定義により、符号付きの結果になります。結果にptrdiff_t
は、符号付き整数型である型があります。
ここで重要な点は、任意の 2 つのポインターだけを減算することは許可されていないということです。結果が定義されるためには、ポインターは同じ配列の要素 (または、架空の「末尾の 1 つ後」の要素) を指す必要があります。
減算の結果は、バイト単位ではなく要素単位で表されます。つまり、C のポインター演算の残りの部分と一貫して機能A - B
しA
ますB
。
ポインターが指している生のアドレス間のバイト数の違いが必要な場合、多かれ少なかれ正式に有効な方法は次のとおりです。
intptr_t difference = (intptr_t) left - (intptr_t) right;
そうすれば、ポインターを減算するのではなく (任意のポインターに対して定義されていないため)、整数表現を減算します。変換の結果(intptr_t) some_pointer
は実装定義ですが、通常はポインターに格納されている物理メモリ アドレスです。残念ながら、この方法にはいくつかの問題があり1
ます。上位ビットを持つポインターに対して誤った結果を生成する可能性があります。このようなポインタは、通常、 に変換されると負の値になりintptr_t
ます。
試す
struct fdBase *left, *right;
void *result = (void *)left - (void *)right;
他の2つのアイデア:
1-使用している関数で、コンパレータが(左<右)の場合は負の数、(左=右)の場合は0、(左>右)の場合は正の数を返す必要があると仮定します。
struct fdBase *left, *right;
if (left < right)
return -1;
else if (left == right)
return 0;
else
return 1;
または、よりコンパクトなバージョン:
if (left < right) ? -1 : (if (left == right) ? 0 : 1)
sizeof(fdBase)
2-減算の差に:を掛けます。
struct fdBase *left, *right;
int result = (int)(left - right) * sizeof(fdBase)
これまでの回答に基づいて、私が欲しいのは次のとおりだと思います。
struct fdBase *left, *right;
ptrdiff_t result = (char *)left - (char *)right;