指针操作产生意外结果

Pointer operation yields unexpected result

我期待下面的代码打印 4(因为浮点数是 4 个字节),但它打印了 1。有人能解释为什么会这样吗?

#include <stdio.h>
int main()
{
    float a[4]={0.0,0.1,0.2,0.3};
    printf("%d", &a[1]-&a[0]);
    return 0;
}

首先,改变

  printf("%d", &a[1]-&a[0]);

 printf("%td", &a[1]-&a[0]);

因为两次减法的结果类型产生一个类型 ptrdiff_t 并且 %td 是该类型的转换说明符。

也就是说,引用 C11,章节 §6.5.6,减法运算符(强调我的

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. [....] In other words, if the expressions P and Q point to, respectively, the i-th and j-th elements of an array object, the expression (P)-(Q) has the value i−j provided the value fits in an object of type ptrdiff_t. [....]

在你的情况下,P&a[1]Q&a[0],所以 i1j0。因此减法运算的结果是i-j,即1-01

你是正确的,两个指针相隔 4 个字节。如果你减去两个整数,你会得到 4。但是 &a[1]&a[0]float * 类型。 Pointer arithmetic in C 考虑到被指向的东西的大小,所以 &a[1]-&a[0] 是 1。

这是数组索引工作的基本方法。您可以利用这一点来遍历数组而不需要单独的索引,而是终止于 NaN.

之类的边界。
#include <stdio.h>
#include <math.h>

int main()
{
    float a[] = { 0.0,0.1,0.2,0.3,NAN };

    float *iter = a;
    while(!isnan(*iter)) {
        printf("%f\n", *iter);
        iter++;
    }
}

如果您将值转换为 unsigned int,您确实会得到 4。

printf("%u\n", (unsigned int)&a[1]-(unsigned int)&a[0]);