做绿色软件的网站知乎,wordpress slides,网站收录是什么,wordpress随机评论插件那这样p和*p记录的地址不一样了吗#xff1f; 不#xff0c;p 和 *p 记录的地址在某种意义上是“相同”的#xff0c;但它们在类型和使用方式上有所不同。 p 的地址#xff1a;p 是一个指针#xff0c;它本身存储了一个地址#xff0c;这个地址是二维数组 arr 的第一行 不p 和 *p 记录的地址在某种意义上是“相同”的但它们在类型和使用方式上有所不同。 p 的地址p 是一个指针它本身存储了一个地址这个地址是二维数组 arr 的第一行或称为第一个一维数组的首元素的地址。因此p 的值即它存储的地址是指向 arr[0][0] 的。 *p 的“地址”当我们说 *p 的地址时实际上有些误导因为 *p 不是一个指针而是一个数组尽管在表达式中它会被退化为指向其首元素的指针。但是如果我们谈论 *p “指向”的地址我们实际上是在谈论 *p即 arr[0]的首元素的地址这与 p 存储的地址是相同的都是 arr[0][0]。
然而重要的是要理解 p 和 *p 在类型和使用上的差异 类型p 的类型是 int (*)[5]即一个指向包含5个整数的数组的指针。而 *p 的类型是 int[5]即一个包含5个整数的数组但在表达式中它会被退化为 int*。 使用你不能直接对 *p 进行赋值或将其作为函数参数传递因为它不是一个左值但你可以通过索引来访问它的元素如 (*p)[0]。而 p 可以被赋值可以作为函数参数传递也可以进行指针算术运算如 p 1 将指向下一行。
为了澄清让我们再次强调p 存储了一个地址这个地址是二维数组第一行的首元素的地址。而 *p 在表达式中会被退化为指向这个首元素的指针但技术上 *p 表示的是整个一维数组的“视图”。然而我们总是通过索引来访问这个数组中的元素。
总结p 和 *p 在“指向”的地址上是相同的都指向 arr[0][0]但它们的类型和使用方式完全不同。 那*p1会得到什么 在C语言中当 *p 表示一个数组尽管在表达式中它通常会被退化为指向其首元素的指针时直接对 *p 进行算术运算如 1是不合法的因为 *p 本身不是一个可修改的左值也不是一个指针。
然而如果你写了 *p 1这里实际上发生的是指针算术的“假象”。由于 *p 在表达式中会被退化为指向数组首元素的指针即 int* 类型*p 1 的结果是一个指向 arr[0][1] 的指针即 arr[0][1]。这里1 是按照指针的步长即指向类型的大小来计算的对于 int* 类型的指针来说步长通常是 sizeof(int)。
但是重要的是要明白这种写法*p 1虽然在技术上是合法的并且可能符合你的预期得到指向下一个元素的指针但它实际上是在对已经退化为指针的 *p 进行操作而不是直接对数组本身进行操作。
如果你想要访问二维数组中的下一个元素比如从 arr[0][0] 移动到 arr[0][1]你应该使用 (*p)[1]。但是如果你想要得到指向下一个元素的指针那么 *p 1 是正确的写法尽管它看起来可能有些令人困惑。
然而如果你想要遍历二维数组的行你应该使用指针 p 本身进行算术运算比如 p 1 会指向二维数组的下一行即 arr[1]。
总结一下
*p 1 得到的是指向 arr[0][1] 的指针。(*p)[1] 访问的是 arr[0][1] 的值。p 1 指向二维数组的下一行。