我期望下面的代码显示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;
}
答案 0 :(得分:7)
首先,更改
printf("%d", &a[1]-&a[0]);
到
printf("%td", &a[1]-&a[0]);
因为两个减法的结果类型产生类型ptrdiff_t
,而%td
是该类型的转换说明符。
也就是说,引用C11
,第§6.5.6章,减法运算符(强调我的)
当减去两个指针时,两个指针都应指向同一数组对象的元素, 或在数组对象的最后一个元素之后; 结果是 两个数组元素的下标。 [....]在 换句话说,如果表达式
P
和Q
分别指向第i
和第j
个元素 如果是数组对象,则表达式(P)-(Q)
的值为i−j
,前提是该值适合类型为ptrdiff_t
的对象。 [....]
在您的情况下,P
是&a[1]
,而Q
是&a[0]
,所以i
是1
,而j
是0
。因此,减法运算的结果为i-j
,即1-0
,1
。
答案 1 :(得分:3)
您是正确的,两个指针相距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]);