鱼C论坛

 找回密码
 立即注册
查看: 62|回复: 4

[萌新报道] *号

[复制链接]
发表于 3 天前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>

int main()
{
        int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        int (*p)[10] = &array;

        printf("%d\n", *(*(p+1)-6));

        return 0;
}这个*(p+1)前面遇到的不是解出来地址里面的值吗,为什么解除来的是个地址,该怎么理解这个*号。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层
首先,您提供的代码有一些错误,需要纠正才能正确理解。让我们先修正代码:

修正后的代码:

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 正确声明数组
  5.     int *p = array; // p指向数组的第一个元素

  6.     // 下面的表达式可能不安全,仅用于解释
  7.     // printf("%d\n", *(*(p+1)-6)); // 原表达式,但会导致未定义行为

  8.     // 为了理解,先分解操作:
  9.     // p+1 指向 array[1] 的地址
  10.     // *(p+1) 得到 array[1] 的值,即 1
  11.     // *(p+1)-6 得到 1-6 = -5
  12.     // *(-5) 尝试解引用地址-5,这是非法的

  13.     return 0;
  14. }
复制代码


关于 * 号的理解:
在C语言中,* 号在表达式中用作“解引用运算符”。它的作用是:获取指针所指向地址中存储的值。例如:
- 如果 p 是一个指向 int 的指针,那么 *p 得到的是 int 类型的值,而不是地址。
- 在您的代码中,pint * 类型,指向数组的第一个元素,所以 *(p+1) 得到的是数组第二个元素的值(即 1),而不是地址。

为什么您会认为解出来的是地址?
可能的原因:
1. 如果指针指向的是指针类型(例如 int **),那么解引用后得到的值本身可能是一个地址。但您的代码中 pint *,所以不是这种情况。
2. 表达式 *(*(p+1)-6) 中,第一个 *(p+1) 得到整数值,然后减去6,再被解引用。这可能导致未定义行为(例如访问非法地址),使输出看起来像地址,但实际上它只是内存中的垃圾值。

正确示例:

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  5.     int *p = array; // p指向array[0]

  6.     printf("p指向的地址: %p\n", (void*)p);
  7.     printf("*(p+1)的值: %d\n", *(p+1)); // 输出1,这是值,不是地址

  8.     return 0;
  9. }
复制代码


总之,* 号解引用后得到的是值,不是地址,除非指针类型是指针的指针。您的困惑可能源于代码中的未定义行为。建议避免此类复杂表达式,确保指针操作安全。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 3 天前 | 显示全部楼层
本帖最后由 Kelekin 于 2025-12-16 20:01 编辑
FishC 发表于 2025-12-16 19:39
首先,您提供的代码有一些错误,需要纠正才能正确理解。让我们先修正代码:

修正后的代码:


我给的是存放整个数组地址的指针,我想问的是这个解出来的是一个值,再-6,这个空间里也没有值啊,还是说这个&号有新增地址的功能,
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 天前 | 显示全部楼层
Kelekin 发表于 2025-12-16 19:59
FishC 发表于 2025-12-16 19:39
首先,您提供的代码 ...


你提到的是指向整个数组的指针,这与指向数组首元素的指针不同。我们来详细分析。

首先,修正代码以使用指向整个数组的指针:

#include <stdio.h>

int main()
{
    int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int (*p)[10] = &array;  // p是指向整个数组的指针,类型为int(*)[10]

    printf("%d\n", *(*(p+1)-6));
    return 0;
}

理解这个表达式:*(*(p+1)-6)

1. p 是指向 int[10] 的指针,即指向整个数组的指针。
2. p+1:根据指针运算,p+1 会跳过整个数组(10个int),指向数组之后的位置。
3. *(p+1):解引用 p+1,得到的是 p+1 指向的“数组”(实际上这个位置并不存在真正的数组,但类型上是 int[10])。在表达式中,数组名会自动转换为指向其首元素的指针,所以 *(p+1) 实际上是一个 int* 类型的指针,指向一个假想的数组的首元素(即 array 之后第10个元素的位置)。
4. *(p+1)-6:这个 int* 类型的指针减去6,即向前移动6个int单位。假设 array 的起始地址为 A,那么:
   - p 指向 A
   - p+1 指向 A + 10*sizeof(int)
   - *(p+1) 转换为指向 A + 10*sizeof(int) 的 int* 指针
   - *(p+1)-6 指向 A + 10*sizeof(int) - 6*sizeof(int) = A + 4*sizeof(int)
   所以,这个指针实际指向 array[4](即第5个元素)。
5. *(*(p+1)-6):解引用这个指针,得到 array[4] 的值,即4。

因此,整个表达式输出的是4。

关键点:
- *(p+1) 并不是解引用得到一个值,而是得到一个数组(但立即转换为指针)。所以 *(p+1) 的结果是一个地址(int* 类型),而不是一个整数值。
- 然后对这个地址进行算术运算,再解引用,最终访问到数组中的元素。

所以,你的疑问“解出来的是一个值,再-6,这个空间里也没有值啊”是不准确的,因为 *(p+1) 解出来的是一个指针(地址),而不是值。然后对这个指针进行减法操作,得到另一个合法地址(指向array[4]),最后解引用得到值。

注意:虽然这个表达式可能输出4,但它依赖于未定义行为(因为 p+1 指向数组之外,解引用 *(p+1) 是未定义的)。实际编程中应避免这种写法。这里仅用于理解指针运算。

如果你希望安全地访问数组元素,建议直接使用数组索引或明确的指针运算。例如:

#include <stdio.h>

int main()
{
    int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *p = array; // 指向数组首元素的指针
    printf("%d\n", p[4]); // 输出4
    // 或者
    printf("%d\n", *(p+4)); // 输出4
    return 0;
}

希望这个解释能帮助你理解。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 09:32 | 显示全部楼层
*不是“一定取出一个数”,而是“按类型取出一个东西”。

你这里取出来的“东西”刚好是一个数组,数组在表达式里会自动变成地址。


把内存想成一排整箱矿泉水:

  • int → 一瓶水
  • int[10] → 一整箱水(10瓶)
  • int (*)[10] → 指向“一整箱水”的标签
  • int (*p)[10] = &array;

p 指的是整箱水

那 p + 1 是什么?

不是“下一瓶”,而是下一整箱水的位置!

重点来了:为什么 *(p + 1) 还是地址?

*(p + 1)你以为是“拆箱取一瓶”,但实际上是:把“整箱水”搬出来

而 C 语言规定:

整箱水(数组)一旦拿出来用,就自动变成“第一瓶的位置”

所以:

*(p + 1)   // 看起来像值
           // 实际上变成了:int *


不是 * 失效了,而是你 * 出来的是数组,数组会自动变成地址。


* 解引用“取对象”,不是“取数值”,你取到的是数组,数组在表达式中天然就表现为地址

记住这个,就不会再被这类题骗了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-12-19 13:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表