为什么在存储和不存储在变量中时,减去数组中连续值的地址会得到不同的值?

问题描述 投票:0回答:2
#include<stdio.h>

int main()
{
    int a[2] = {1,3};
    long a0 = &a[0];
    long a1 = &a[1];
    printf("%ld - %ld = %d\n\n", &a[1], &a[0], ((&a[1]) - (&a[0]))); // prints 1
    printf("%ld - %ld = %d\n\n", a1, a0, a1 - a0); // prints 4
    printf("size of a0 [%ld] is %d\n", a0, sizeof(a0)); // prints [some number] and 8
    return 0;
}

我不明白为什么它在两个 print 语句中都打印 1 而不是 4

按照理解,&a[1] 获取第 2 个 4 字节内存块中第 1 个字节的下一个地址。 类似地,&a[0] 获取第一个 4 字节内存块中第一个字节的地址。 存储为长数据类型并减去打印 4。但是减去而不存储给出 1。你能帮我理解吗?谢谢!

c pointers
2个回答
0
投票

类型

long
与表达式
&a[0]
的类型(即
int *
)不兼容。如果你解决了这个问题,差异就会消失:

    int *a0 = &a[0];
    int *a1 = &a[1];

当你减去两个指针时,你会得到该类型的元素数量。这是字节数除以类型的另一种说法。当您减去两个长值时,您会得到您从基础数学中期望的值。

    


0
投票

    sizeof
  • a[i]
    的简写。
    将数组视为指针会产生指向其第一个元素的指针。
要使
*( a + i )

正常工作,

a[i]
不得将
a + i
添加到地址,而是添加
i
。所以它被定义了。
i * sizeof(*a)


uint64_t a[2]; printf( "%p\n", (void*)&a ); // 0x1000 Type: uint64_t (*)[2] printf( "%p\n", (void*)&a[0] ); // 0x1000 Type: uint64_t* printf( "%p\n", (void*)&a[1] ); // 0x1008 Type: uint64_t* printf( "%p\n", (void*)&a[0]+0 ); // 0x1000 Type: uint64_t* printf( "%p\n", (void*)&a[0]+1 ); // 0x1008 Type: uint64_t*

呢?

我们知道 

&a[1] - &a[0]

&a[0] + 1
所以 
&a[1]
一定是
&a[1] - &a[0]
,
即使指针的地址相隔 8 个。

1

© www.soinside.com 2019 - 2024. All rights reserved.