我正在寻求有关地址递增如何影响指针的解释。
我了解了C指针如何工作以及如何通过考虑指针类型来增加指针。我还是不明白以下情况
int main()
{
int a[] = {1,2,3,4,5};
int *p = (int*)(&a+1);
printf("%d\n%d\n", *(a+1), *(p-1));
return 0;
}
我希望这条线
int *p = (int*)(&a+1);
使p指向数组“ a”之后的地址,因此我期望输出:
2-因为它只是一个[1]
unknown_number-,因为我不知道哪个int落后(&a + 1)4个字节
但实际结果是:
2
5
为什么p似乎直接指向a之后的内存?
我感到困惑的原因是什么?
答案 0 :(得分:3)
因此,在此示例中,&a
的类型为int(*)[5]
。当您向其添加1时,它实际上会添加sizeof(int[5])
-因为这是指针算术的工作方式,所以添加偏移量将指向的类型的大小乘以偏移量。这样,您就可以使p
成为a
的最后一个元素,然后将其强制转换为int*
,因此现在您有了一个指向整数的指针,该指针指向地址后面的整数。 a
的最后一个元素。因此,从中减去1可以得到a
的最后一个元素。
答案 1 :(得分:1)
您可以将数组a
用作指向整数int *
的指针。但这与&a
不同,&a + 1
是指向5个整数的数组的指针:&
会将5个整数的大小添加到指针。
只需在将1加到a之前删除#include <stdio.h>
int main()
{
int a[] = {1,2,3,4,5};
int *p = (int*)(a+1); // & removed
printf("%d %d\n", *(a+1), *(p-1));
return 0;
}
,它便会按预期工作:
.avatar {
margin: 10px;
border-radius: 50%;
height: 90px;
text-align: center;
width: 90px;
border: 5px solid #fafafa;
background-color: blue;
}
.initials {
font-size: 2rem;/* 50% of parent */
position: relative;
top: 1.2rem; /* 25% of parent */
color: #fafafa;
font-weight: 700;
}
.update-homepage-link {
color: #fafafa;
font-weight: bold;
color: pink;
}
答案 2 :(得分:1)
两个基本概念:
除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化声明中的字符数组的字符串文字,即 expression 类型为“ T
的N元素数组的em>将被转换(“衰变”)为类型为“指向T
的指针”的表达式,该表达式的值将为数组的第一个元素。
在类型“指向T
的指针”的表达式中加1会产生紧跟当前对象的T
类型的对象的地址。 IOW,如果p
指向一个4字节的int
,则p+1
指向紧随其后的int
。如果p
指向int
的5元素数组,则p+1
指向紧随其后的int
的下一个5元素数组。这就是数组索引的工作方式-下标操作a[i]
被定义为*(a + i)
。给定起始地址a
(指针表达式或衰减到指针的数组表达式),请在该地址之后找到第i
个 object 的地址并取消引用结果。
所以,如果您有声明
int a[] = {1, 2, 3, 4, 5};
那么以下是正确的:
表达式 a
的类型为“ int
的5元素数组”(int [5]
)-如果表达式不是以下内容的操作数sizeof
或一元&
运算符,它会“拒绝”键入“指向int
的指针”(int *
),其值是数组第一个元素的地址({&a[0]
)。
表达式*(a + 1)
与a[1]
相同,其结果为数组(2
)中的第二个对象。
表达式&a + 1
的类型为int (*)[5]
,并在int
之后产生a
的5元素数组的起始地址。该表达式的类型将转换为int *
并分配给p
。
表达式p
的类型为int *
-从中减去1将得出int
紧前面的p
对象的地址,该地址恰好是最后一个a
的元素。
以图形方式:
+–––+
a: | 1 |
+–––+
| 2 | <–– a + 1
+–––+
| 3 |
+–––+
| 4 |
+–––+
| 5 | <–– p - 1
+–––+
| ? | <–– p (&a + 1)
+–––+