You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何指针修改结构体成员值时需使用取地址运算符?

为什么两个代码示例中scanf的参数写法有差异?

这个问题其实搞清楚scanf的核心要求,再结合指针、结构体成员的访问逻辑就通了,咱们一步步拆解:

先明确scanf的本质要求

scanf("%d", ...)的第二个参数必须是要存储输入值的内存地址——它需要知道“把用户输入的数字放到哪块内存格子里”,给它地址才能准确定位。


看代码示例2的逻辑

void input(int *precord) {
  scanf("%d", precord);
}

这里的precord是int*类型的指针,它从主函数的input(&age)里接收到的,就是age这个int变量的内存地址。

换句话说,precord本身就是个“装地址的盒子”,里面装的正好是scanf需要的目标地址,所以直接把precord传给scanf就行,完全符合要求。


再看代码示例1的逻辑

void input(struct student *precord) {
  scanf("%d",&precord->a);
}

这里的precord是struct student*类型的指针,它接收到的是整个student结构体的地址。而我们要修改的是结构体里的a成员(一个int变量),不是整个结构体。

precord->a是通过指针访问结构体的成员,得到的是这个int成员本身(或者说,是这个成员的数值/内存内容),而不是它的地址。所以我们必须用&取地址运算符,拿到这个成员变量的内存地址,再传给scanf——这样scanf才知道要把输入的数放到结构体的a成员所在的内存格子里。

补充个小细节:->的优先级比&高,所以&precord->a等价于&(precord->a),先找到结构体的a成员,再取它的地址,逻辑是对的。


总结差异的核心

  • 示例2中,指针直接存储的是目标变量的地址,所以直接传指针给scanf;
  • 示例1中,指针存储的是结构体的地址,我们要操作的是结构体内部的成员,所以需要先访问到该成员,再取它的地址传给scanf。

内容的提问来源于stack exchange,提问作者LooserLothbrok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:16:15