1

在C中,以下工作吗?

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

result可以是负数。如果这不起作用,我该怎么写?

我的目标是为我的红黑树排序函数提供一些东西,即所谓的指针“比较器”。我不是在做数组工作,我需要指针之间的实际差异,以字节为单位。

4

3 回答 3

7

根据定义,C 中两个指针相减的结果具有带符号的结果。结果具有ptrdiff_t类型,即有符号整数类型。

这里重要的细节是你不能只减去两个任意指针。为了定义结果,指针必须指向同一数组的元素(或指向假想的“结束后一个”元素)。

减法的结果以元素表示,而不是以字节表示,即它与 C 中的其余指针算术一致。如果指向索引大于 的元素A - B,则结果可以并且将为负数。AB

如果您需要指针指向的原始地址之间的字节差异,则或多或少正式有效的方法如下

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;

另外两个想法:

1 - 假设您使用的函数要求您的比较器在 (left < right) 时返回负数,如果 (left = right) 则返回 0,如果 (left > right) 则返回正数:

    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)

2 - 将减法的差乘以sizeof(fdBase)

    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 回答