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

为何在scanf中传入&a[i].name会触发类型不匹配警告?

关于scanf中字符数组参数的类型疑问解答

为什么加&a[i].name会触发警告?

  • a[i].name是长度为10的char数组的数组名。在C语言的表达式中(除sizeof、&操作符等少数场景外),数组名会自动隐式转换为指向数组首元素的指针,也就是char*类型,这正好匹配scanf的%s格式符要求的参数类型——%s需要接收一个指向字符数组起始位置的指针,用来存储输入的字符串。
  • 当给a[i].name加上&取地址操作符后,&a[i].name的类型变成了char (*)[10](指向长度为10的char数组的指针),这个类型和%s要求的char*不兼容,因此编译器会抛出类型不匹配的警告。

为什么普通变量要加&,数组却不用?

  • 对于普通变量(比如a[i].roll这类int变量),变量名代表的是变量存储的值,如果要让scanf把输入写入变量的内存地址,必须用&取地址,得到int*类型的指针,匹配%d格式符的参数要求。
  • 数组名的特性特殊:它在表达式中会自动转换成指向首元素的指针,相当于已经提供了数组的起始地址,所以不需要额外加&。虽然a[i].name和&a[i].name的地址数值完全相同,但它们的类型语义不一样——前者指向单个字符,后者指向整个长度为10的字符数组。

额外验证

你可以在代码中加入下面的打印语句,观察地址值和类型的区别:

printf("a[i].name的地址:%p,类型为char*\n", a[i].name);
printf("&a[i].name的地址:%p,类型为char (*)[10]\n", &a[i].name);

运行后会发现两个地址的数值完全相同,但编译器对它们的类型判定是不一样的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 02:24:11