指针算术 - 数组和指向数组的指针的问题

Pointer Arithmetic - Issues with array and pointer to an array

我最近切换到 C 并试图找出指针。

#include <stdio.h>

int main()
{
    int arr[5] = {1,2,3,4,5};
    int *a = &arr;

    printf("Array : %p\n", arr);
    for(int i=0; i<5; i++)
    {
        printf("Value and Address of Element - %d : %d\t%p,\n", i+1, arr[i], &arr[i]);
    }
    printf("Pointer to the Array : %p\n", a);
    printf("Value pointed by the pointer : %d\n", *a);
    a = (&a+1);
    printf("Pointer after incrementing : %p\n", a);
    return 0;
}

但是,下面这行似乎不起作用。

a = (&a+1);

打印指针a的增量值后,它仍然指向数组(arr)。 这是程序的输出:

Array : 0x7ffe74e5d390
Value and Address of Element - 1 : 1    0x7ffe74e5d390,
Value and Address of Element - 2 : 2    0x7ffe74e5d394,
Value and Address of Element - 3 : 3    0x7ffe74e5d398,
Value and Address of Element - 4 : 4    0x7ffe74e5d39c,
Value and Address of Element - 5 : 5    0x7ffe74e5d3a0,
Pointer to the Array : 0x7ffe74e5d390
Value pointed by the pointer : 1
Pointer after incrementing : 0x7ffe74e5d390

如您所见,指针 'a' 仍然指向第一个元素。但是,理论上 'a' 不应该指向最后一个元素之后的任何内容(假设 &a + 1 将指针递增整个数组的大小 - 来源:difference between a+1 and &a+1

有人可以解释为什么吗?

在这种特殊情况下,变量和数组可以像下面这样放置在堆栈上,标准不保证这一点。每个单元格都是整数。你还记得每次放置局部变量时堆栈地址都会减少吗?

+-+-+-+-+-+-+
|a|1|2|3|4|5|
+-+-+-+-+-+-+

&a+1,不是数组的地址,你取a的地址,往前移动一个单元格,结果就是数组的地址。

a = (&a+1); 设置 a 指向 a.

地址之外的一个“东西”

之前,您的代码使用 int *a = &arr;a 设置为 &arr。 (这违反了标准 C 约束,因为 &arr 的类型是指向数组的指针,而不是指向 int 的指针。正确的定义是 int *a = arr;。)我怀疑你的意图a = (&a+1); 是将 a 设置为指向一个超出当前指向的位置。但是,正确的代码是 a = a+1;。它将 avalue 加一,并将结果赋给 a。 相反,a = (&a+1); 使用 a 的地址而不是它的值。

这导致 a 指向内存中 a 之外的一个。在您的实验中,似乎数组 arr 碰巧在那里,并且您的 C 实现相应地表现。

(这解释了您观察到的结果,但这不是您应该依赖的行为。C 标准没有定义当您以这种方式滥用指针时会发生什么,包括编译器优化在内的各种事情都可能导致程序表现得好像 &a+1 没有指向 arr,即使 arr 实际上位于内存中的地址 &a+1。)