c++ 使用指针引用和取消引用数组时出现意外行为

ct3nt3jp  于 2023-03-20  发布在  其他
关注(0)|答案(3)|浏览(143)

下面是代码:

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。

swvgeqrz

swvgeqrz1#

您的问题的答案就在您(可能)在插入(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-ints-each数组,则下一个5-int数组将位于何处),* 而不是 * 到数组中的第二个int
因此,当您在代码中计算*(p-1)时,您将获得一个指向&a[5]的指针(该指针并不存在,但不必在意),然后从中减去1 int,这将为您提供一个指向&a[4]的指针,您将解引用该指针以从数组中获取值5

7vux5j2d

7vux5j2d2#

以下是代码的工作原理

整数a[5] = { 1,2,3,4,5 };创建具有5个元素的整数数组A,并使用值1、2、3、4和5对其进行初始化。
整数p =(整数)(&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。
如果你有任何困惑就告诉我。

dluptydi

dluptydi3#

问题是数组的标识符(变量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[]在指针方面有些相似,但并不完全相同。

相关问题