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

为何scanf第3个参数需用取地址符而第2个不用?兼谈->运算符

关于scanf参数与指针箭头运算符->的疑问解答

一、为什么scanf中(ptr+i)->name不用加&,而(ptr+i)->age需要?

首先明确scanf的核心要求:所有接收输入的参数必须是指针,因为scanf需要通过指针定位内存地址,把输入的值写入对应空间。

  • 对于(ptr+i)->name:
    name是结构体里的char name[30]数组,在C语言中,数组名本身就是指向数组第一个元素的指针,等价于&name[0]。直接传(ptr+i)->name,本质是传递了字符数组首元素的地址,完全符合scanf对%s格式符的指针要求(%s需要接收char*类型指针存储字符串)。

  • 对于(ptr+i)->age:
    age是结构体里的int类型变量,它本身是一个数值而非指针。如果直接传(ptr+i)->age,相当于把age当前的数值传给scanf,不符合scanf的指针要求,编译器就会报错“不是指针”。加&是为了获取这个int变量的内存地址(即int*类型指针),这样scanf才能把输入的整数写入到对应内存空间中。

二、指针箭头运算符->的用法

->是专门用于通过结构体指针访问结构体成员的运算符,是(*指针).成员的简化写法,目的是让代码更简洁易读。

结合你的代码来看:

  • ptr是指向struct person类型的指针(大概率指向一个struct person数组的首地址)。
  • ptr+i表示指针向后偏移i个struct person的内存大小,指向数组中的第i个结构体元素。
  • (ptr+i)->name 等价于 (*(ptr+i)).name:先对ptr+i解引用(拿到对应的结构体实例),再访问它的name成员。
  • 同理,(ptr+i)->age 等价于 (*(ptr+i)).age,用于访问第i个结构体的age成员。

用->而非(*指针).成员,是因为后者需要加括号保证运算优先级(.的优先级高于*),写起来繁琐,->则更直观简洁。

你的代码参考

// 结构体定义
struct person {
    int age;
    float weight;
    char name[30];
};

// 循环输入代码
for(i = 0; i < n; ++i)
{
    printf("Enter name of person %d and age respectively: ", i);
    // 访问第i个person结构体成员
    scanf("%s %d", (ptr+i)->name, &(ptr+i)->age);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:05:24