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

为何cin无需像scanf那样使用取址符或格式说明符?附代码疑问

关于C++中cin >>运算符的疑问解答

核心原理:std::cin的>>运算符重载规则

std::cin是std::istream类的实例,>>运算符的行为完全依赖于标准库提供的重载版本:

  • 对于基本数据类型(如int、float等),对应的重载是:std::istream& operator>>(std::istream&, T&)(T为基本类型)。这个版本要求传入一个可修改的左值引用,目的是让cin能把读取的值直接写入到目标变量的内存中。
  • 仅对char*类型提供了特殊重载:std::istream& operator>>(std::istream&, char*),用于读取C风格字符串到指定的字符数组中。

问题1:为什么cin >> (p+i)报错,而cin >> p[i]/cin >> *(p+i)可行?

先明确各个表达式的类型:

  • p[i] 和 *(p+i):两者完全等价,都是int类型的左值(指向堆上第i个int元素的内存位置,可被修改)。它们能直接匹配operator>>(istream&, int&)重载,cin会把读取的值写入到这个内存位置,所以写法正确。
  • p+i:这是一个int*类型的右值(计算出来的是指向第i个int元素的地址值,但本身是一个临时的指针值)。标准库没有为int*类型提供>>运算符重载,编译器找不到匹配的函数,因此报错。

你误以为cin >> (p+i)等同于cin >> &p[i],但实际上&p[i]也是int*类型,同样没有对应的重载,所以这个写法也会报错——你的这个假设本身就是错误的,&p[i]并不能用来给cin传参。


问题2:为什么cin >> n可行,而cin >> &n不行?

  • n是int类型的左值,能绑定到int&,匹配operator>>(istream&, int&)重载,cin可以直接把输入值写入n的内存,所以可行。
  • &n是int*类型的指针值,同样没有对应的>>重载,编译器无法找到匹配的函数,因此报错。

验证示例

#include <iostream>
using namespace std;

int main() {
    int n = 3;
    int* p = new int[n];

    // 正确写法:传入int&
    for (int i = 0; i < n; i++) {
        cin >> p[i]; // 等价于 cin >> *(p+i);
    }

    // 错误写法:传入int*,无对应重载
    // for (int i = 0; i < n; i++) {
    //     cin >> (p + i); // 编译报错
    //     cin >> &p[i];   // 同样编译报错
    // }

    // 输出验证
    for (int i = 0; i < n; i++) {
        cout << p[i] << " ";
    }
    delete[] p;
    return 0;
}

如果非要用指针地址的方式传入cin,你可以把指针解引用,转换成int&:

cin >> *(p + i); // 这就是正确的写法,本质是把int*转换成int&

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:11:02