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

问题描述 投票:-1回答:1

我最近换成了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将指针按整个数组的大小递增--源。a+1和&a+1之间的区别。)

谁能解释一下原因?

c++ c arrays pointers pointer-arithmetic
1个回答
1
投票

a = (&a+1);a 指着一个 "东西 "之外 地址 a.

之前,你的代码集 a&arr,使用 int *a = &arr;. (这违反了标准的C约束,因为类型为 &arr 是指向数组的指针,而不是指向一个 int. 正确的定义是: int *a = arr;.) 我怀疑你的意图是 a = (&a+1); 是要设置 a 指向一个超出当前指向的地方。然而,正确的代码应该是 a = a+1;. 这需要 价值a,在其上加一,并将结果赋值给 a.相比之下,。a = (&a+1); 的地址。a 而不是其值。

这就导致了 a 遥指 a 在内存中。在你的实验中,似乎数组 arr 碰巧在那里,而你的 C 实现也会相应地表现出来。

(这解释了你观察到的结果,但这不是你应该依赖的行为。C标准并没有定义当你以这种方式滥用指针时会发生什么,各种事情,包括编译器优化,都会导致程序的行为就像 &a+1 并未指向 arr 纵然 arr 事实上,它的地址是 &a+1 在内存中)。)


0
投票

在这种特殊情况下,变量和数组可以像下面这样放在堆栈上,但标准并不保证。每个单元都是int。你还记得堆栈地址是在每个本地变量放置时减少的吗?

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

&a+1这不是数组的地址,你取a的地址,在一个单元格上移动,得到数组的地址作为结果。

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