关于c++ pionter的困惑

问题描述 投票:0回答:3

代码如下:

int a[5] = { 1, 2, 3, 4, 5 };
int* p = (int*)(&a + 1);
printf("%d, %d", (*a+1), *(p - 1));\
// output 2, 5

因为我相信 p 指向数组 a 中的第二个元素,即 2。所以 *(p-1) 的输出是 1。 但是在VS *(p-1)输出5,是什么原因呢? 感谢您的帮助!

我相信输出应该是 2, 1.

c++ arrays pointers
3个回答
3
投票

您的问题的答案在于您(可能)在插入

(int*)
转换以覆盖编译器的更好判断之前看到的错误消息:

int* p = (&a + 1);

temp.cpp:7:10: error: cannot initialize a variable of type 'int *' with an rvalue of type 'int (*)[5]'
    int * q = &a;

因为

a
int[5]
类型,这意味着
&a
pointer-to-int[5]
类型,也意味着
sizeof(a)
等于
5*sizeof(int)
...这意味着
(&a+1)
指向到数组末尾后的地址(即如果你有一个 5 整数数组的数组,下一个 5 整数数组的位置),not 到第二个
int
你的数组。

所以当你在你的代码中评估

*(p-1)
时,你正在获取一个指向
&a[5]
的指针(它不存在,但没关系)然后从中减去 1
int
,这给你一个指向
&a[4] 的指针
,您取消引用以从数组中获取值
5


0
投票

问题是数组的标识符(变量a)即a存储数组本身的起始指针

你已经写了 (&a + 1) 所以它将整个数组视为一个指针并且 +1 指向 p 到数组大小之后的下一个位置

例如。数组地址为 100,104,108,112,116

&a+1 -> 120

使用 a+1 而不是 &a+1

a+1 -> 104

所以新代码将是

int a[5] = { 1, 2, 3, 4, 5 };
int* p = (int*)(a + 1);
printf("%d, %d", (*a+1), *(p - 1));

这给出了预期输出 2,1

希望这能消除疑虑

更多的是说 int *a 和 int a[] 在指针上有些相似,但不完全相同。


0
投票

以下是代码的工作原理

int a[5] = { 1, 2, 3, 4, 5 };创建一个包含 5 个元素的整数数组 a 并使用值 1、2、3、4 和 5 对其进行初始化。

int* p = (int*)(&a + 1);创建一个整数指针 p 并将其设置为数组 a 末尾的地址。 &a 表达式返回一个指向整个数组 a 的指针,向它加 1 会使指针前进数组的大小,即 sizeof(int) * 5 个字节。然后指针被转换为 int* 类型。

(*a+1) 的计算结果为 1+1,等于 2。*a 周围的括号是不必要的,因为 a 是一个数组并且可以衰减到指向其第一个元素的指针。

*(p - 1) 访问 p 指向的地址前一个整数地址处的值。由于 p 指向的是 a 末尾刚过去的地址,因此 p-1 指向 a 的最后一个元素,即 5.

因此printf语句的输出为2, 5.

如果您有任何困惑,请告诉我。

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