指针操作产生意外结果
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]
,所以 i
是 1
和 j
是 0
。因此减法运算的结果是i-j
,即1-0
,1
。
你是正确的,两个指针相隔 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]);
我期待下面的代码打印 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
andQ
point to, respectively, thei
-th andj
-th elements of an array object, the expression(P)-(Q)
has the valuei−j
provided the value fits in an object of typeptrdiff_t
. [....]
在你的情况下,P
是 &a[1]
,Q
是 &a[0]
,所以 i
是 1
和 j
是 0
。因此减法运算的结果是i-j
,即1-0
,1
。
你是正确的,两个指针相隔 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]);