void元素上的指针减法

时间:2014-07-13 18:36:29

标签: c pointers pointer-arithmetic

编辑:基本上,我试图在向量中确定,给出一个元素,下一个元素是什么。元素是连续的。下面的表达式应该将第一个元素作为前一个元素传递,它应该返回指向第二个元素的指针。我希望距离返回前一个指针的差异,以及第一个指向第二个元素的位置...

我有这个表达:

int next = *(char *)v_next(vec, vec_first(vec));

然后在被调用的函数中,我有这一行来确定一个指针与另一个指针的位置。

void *v_next(const vector *vec, const void *previous) {
    ...
    void *first = cvec_first(cv);
    int distance = (char*) &previous - (char*) &first;

然而,当我比较第一个元素和第二个元素时,它返回的距离为32.如果我将这个距离除以char *的大小,我得到8.那也很明显。将一个指针与另一个指针分开的许多字节,因此这个表达式找不到合适的位置...

    next = (char*) vec->elems + vec->elemsz + distance;

如何让减法正常工作?

2 个答案:

答案 0 :(得分:2)

问题是你需要减去适当的“未确定”类型的指针(无论你的情况如何)。请参阅以下示例:

#include <stdio.h>

int main(void)
{
    int a[] = {1, 2, 3, 4, 5}, *p, *q;

    p = a;
    q = a + 1;

    printf("Corect distance: %d\n", (int) (q - p));
    printf("Incorrect distance: %d\n", (int) ((char *)q - (char *)p));

    return 0;
}

请注意,pq必须指向同一个数组,或更准确地说(C99 6.5.6加法运算符):

  

[...]到同一个数组对象的元素,或者超过最后一个元素的元素   数组对象;结果是两个数组元素的下标不同。

否则就是UB。 substaction的结果具有实现定义的类型ptrdiff_t(这就是我将结果转换为int的原因)。

答案 1 :(得分:0)

你正在比较错误的指针。 &first是变量的位置,它是一个局部变量。 &previous也是如此。所以你要比较两个与向量中的内容无关的指针。

从你的第三个语句看起来你想要以字节为单位的偏移量。如果是这样的话,你不应该把它分开。它由以下人员给出:

int distance = (char*)previous - (char*)first;

(请注意,根据您的体系结构,您可能希望使用ptrdiff_t而不是int。)

您对下一个的陈述应该有效,但它也应该与:

相同
next = (char*)previous + vec->elemsz;
  

我试过了,但是当我使用上面以“int next”开头的表达式时,它只打印0。

那是因为你的第一行,你只读了一个字节(char):

int next = *(char *)v_next(vec, vec_first(vec));
           ^^^^^^^^^

你在这里输入了错误的类型。你想要转换为存储在向量中的类型,我猜测它是int。所以它应该是:

int next = *(int *)v_next(vec, vec_first(vec));