我不知道编译器在做什么++*p;
谁能形象地解释一下这段代码的内存内部发生了什么?
int main()
{
int arr[]={1,2,3,4};
int *p;
p=arr;
++*p;
printf("%d",*p);
}
答案应该是2
原因是 ++*p 实际上是将数组中的第一个成员增加 1。
您正在通过创建另一个指向该元素的 int 指针来递增该数组中的第一个p
元素。线
++*p
递增 p 指向的对象的值 - 在这种情况下,它是数组中的第一个元素。
让我们采取这一行:
++*p
这将首先取消引用 p 指针,因此访问 arr[0],然后递增它。
如果你现在打印 arr[0],它将是 2。
然后打印 *p 与打印 arr[0] 相同,它等于 2。
尝试用 41 替换第一个元素,您的代码将打印 42。
当你有一个指针int *p
时, thenp
表示“内存地址p
指向并且*p
表示“内存地址的内容p
指向”。++
表示预增量,这意味着将值增加 1。由于一元运算符的关联性,例如*
和++
(前缀运算符)是从右到左的,并且比从右到左遍历时*
更接近,在之前操作。因此表示“递增指向的值”,而不是“递增然后获取值”。更清楚写,但它的意思是一样的。p
++
*
++
++*p
p
p
++(*p)
要理解的是“增加指针”之间的区别,这意味着指向另一个值(例如++p
)和“增加指针指向的值”(例如++*p
)。
你可以解决这个问题,但这就是你理解它所需的所有信息。
组成实际的内存地址并使用“ma”作为内存地址
在从 1000 开始的内存地址处,我们有 4 个连续的 4 字节 (sizeof(int) = 4) 插槽。每个槽包含数组初始值设定项中给定的整数值:
arr
ma1000 ... ma1015
_____________________
| 1| 2| 3| 4|
_____________________
arr 给出了 4 个 int 插槽的起始地址以及有多少个。p 保存一个整数的地址,并引用内存中位于位置 2000 的一个 8 字节插槽(假设我们在一个64 位系统上,其中指针为 8 个字节 - 64 个地址位/每字节 8 位)。语句之后p = arr, p 保存地址 1000
p *p or arr[0]
ma2000 .. ma2007 ma1000 .. ma1003
__________ ________
| 1000| | 1 |
__________ ________
*p 给出 p 指向的内存地址的值。p 保存内存地址 1000,内存地址 1000 包含 1,因此 *p 结果为 1。
++*p 表示要增加 p “指向”的 int 的值。p 保存内存地址 1000,它保存值 1。地址 1000 处的值然后从 1 变为 2
arr
ma1000 ... ma1015
_____________________
| 2| 2| 3| 4|
_____________________
printf 然后在 p“指向”的地址打印 int 值,即 2。
p *p or arr[0]
ma2000 .. ma2007 ma1000 .. ma1003
___________ ___________
| 1000| | 2|
___________ ___________
这是理解指针的一个非常基本的概念。
p = arr ;
上面的代码将使指针“ p ”指向“ arr ”所指向的内容。“ arr ” 本身指向第一个元素。
*arr = *(arr + 0) = arr[0] = 1
*(arr + 1) = arr[1] = 2
*(arr + 2) = arr[2] = 3
等等......所以现在当你这样做时++(*arr) that means ++(1) = 2
作为p = arr
,您可以进行剩余的替换和数学运算。