我最近换成了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之间的区别。)
谁能解释一下原因?
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
在内存中)。)
在这种特殊情况下,变量和数组可以像下面这样放在堆栈上,但标准并不保证。每个单元都是int。你还记得堆栈地址是在每个本地变量放置时减少的吗?
+-+-+-+-+-+-+
|a|1|2|3|4|5|
+-+-+-+-+-+-+
&a+1
这不是数组的地址,你取a的地址,在一个单元格上移动,得到数组的地址作为结果。