1

Cでは次のように動作しますか?

struct fdBase *left, *right;
int result = (int)(left - right);

result負になる可能性があります。それがうまくいかない場合、どのように書きますか?

私の目標は、ポインタのいわゆる「コンパレータ」である赤黒木ソート関数に提供するものを持つことです。私は配列作業を行っていません。ポインタ間の実際の差がバイト単位で必要です。

4

3 に答える 3

7

C での 2 つのポインターの減算の結果は、定義により、符号付きの結果になります。結果にptrdiff_tは、符号付き整数型である型があります。

ここで重要な点は、任意の 2 つのポインターだけを減算することは許可されていないということです。結果が定義されるためには、ポインターは同じ配列の要素 (または、架空の「末尾の 1 つ後」の要素) を指す必要があります。

減算の結果は、バイト単位ではなく要素単位で表されます。つまり、C のポインター演算の残りの部分と一貫して機能A - BAますB

ポインターが指している生のアドレス間のバイト数の違いが必要な場合、多かれ少なかれ正式に有効な方法は次のとおりです。

intptr_t difference = (intptr_t) left - (intptr_t) right;

そうすれば、ポインターを減算するのではなく (任意のポインターに対して定義されていないため)、整数表現を減算します。変換の結果(intptr_t) some_pointerは実装定義ですが、通常はポインターに格納されている物理メモリ アドレスです。残念ながら、この方法にはいくつかの問題があり1ます。上位ビットを持つポインターに対して誤った結果を生成する可能性があります。このようなポインタは、通常、 に変換されると負の値になりintptr_tます。

于 2012-10-05T22:17:29.450 に答える
0

試す

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)
于 2012-10-05T22:48:04.573 に答える
0

これまでの回答に基づいて、私が欲しいのは次のとおりだと思います。

struct fdBase *left, *right;
ptrdiff_t result = (char *)left - (char *)right;
于 2012-10-05T22:54:30.557 に答える