欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > c++_cout的理解和使用

c++_cout的理解和使用

2025/6/19 17:36:29 来源:https://blog.csdn.net/weixin_54946088/article/details/148741664  浏览:    关键词:c++_cout的理解和使用

问题引入

cout << (uf.is_same_set(x, y)) ? 'Y' : 'N'<<endl;

请问大家,这条语句对吗?(这里的uf.is_same_set(x, y)是一个自定义函数,返回bool值;所以不是问题的关键)==》

答案是这条语句报错了。我再写了以下的语句,却能准确无误。

  cout << ((uf.is_same_set(x, y)) ? 'Y' : 'N') << endl;

为什么呢? ==》

1.这是因为第一条语句中,<<的优先级会高于三目运算符,即它先返回的是 ostream&;

然后会再执行ostream?'Y':'N'部分;三目判断返回'Y'

但是'Y' 是 char 类型,不是一个可以用 << 运算的对象。

2.cout << ((uf.is_same_set(x, y)) ? 'Y' : 'N') << endl; 这个表达式会先执行三目,返回‘Y’或者‘N’;然后变为:cout<<'Y'<<endl; 所以就没有错。

基于这个问题,我们今天就来聊聊cout

cout是什么?

cout 是一个全局的 输出流对象,本质上是 ostream 类的一个实例,通过 运算符重载(operator<<,实现了类似 cout << x 这样的打印效果。

此外还有其他流对象是:

名称类型功能
cinistream标准输入流
cerrostream错误输出流
clogostream日志输出流

为什么能用 << 打印?

这是 C++ 的经典设计:通过重载运算符 <<(插入运算符)来模拟输出操作。它的原型类似于这样:即它使重载的运算符函数;

ostream& operator<<(ostream& os, int value);
ostream& operator<<(ostream& os, const char* str);
ostream& operator<<(ostream& os, char c);
ostream& operator<<(ostream& os, double d);
ostream& operator<<(ostream& os, bool b);
// 等等,针对不同类型都做了重载

这就意味着你可以这样使用:

cout << "Hello" << ' ' << 42 << ' ' << true;

它的底层执行顺序是:

cout << "Hello"          // 返回 ostream&<< ' '             // 继续插入<< 42              // 继续插入<< ' '             // ...<< true;           // 一连串流式操作

因为每次 << 都返回 ostream&,所以可以链式调用。


输出是怎么“流”到控制台的?

cout 内部持有一个缓冲区(buffer),你每调用一次 <<,其实是将数据写入这个缓冲区。只有当你:

  • 显式使用 endl(刷新并换行);

  • 或缓冲区满;

  • 或程序结束前清理资源;

才会真正把内容输出到终端控制台所以我们便能理解下面两条语句的区别了。

cout << "hello\n";       // 可能只是写进缓冲区
cout << "world" << endl; // 此时强制刷新缓冲区

endl 是什么?

endl 是一个特殊的东西,它不是字符串,而是一个 函数指针,原型是:

ostream& endl(ostream& os);

它的作用是:

  1. 向流中插入一个换行符(\n);

  2. 刷新缓冲区(flush);

所以cout << "Hello" << endl; 等价于:

cout << "Hello";
cout.put('\n');
cout.flush();

自定义类型如何支持 << 输出?

你可以为你的类自己写一个 << 重载,让 cout << 对象 成为可能:

class Person {
public:string name;int age;
};
​
// 重载 <<
ostream& operator<<(ostream& os, const Person& p) {os << "Name: " << p.name << ", Age: " << p.age;return os;
}

这样你就能这样写:

Person p{"麦兜", 20};
cout << p << endl;

ok,这个知识点实际上涉及到了运算符重载函数的编写;我先说一个结论:

operator<<必须写成全局函数(或友元函数),为什么呢?

因为 cout << p 是这样调用的:operator<<(cout, p); // ostream 是左边,Person 是右边

如果你写成:

class Person { ostream& operator<<(ostream& os); // 错误!只能是 p << cout 
};

这就变成了 p << cout,方向颠倒了,所以没法实现 cout << p 的语法。

故哪些运算符建议写成成员函数?哪些建议全局?

运算符类型推荐形式说明
=, [], (), ->成员函数这些操作符需要访问类的内部状态或作用于“左侧对象本身”
<<, >>, +, -, ==, !=全局函数或友元函数左侧不是类对象(如 cout << obj),或需要双操作数对称性

cout的使用技巧

  1. 运算符优先级陷阱 (如我们上面的问题)

  2. 输出 bool 值时注意格式

cout << true << endl;      // 输出: 1
cout << boolalpha << true << endl;  // 输出: true ✅

   3.输出字符和整数要区

    char ch = 'A';
    int x = 65;
    cout << ch << endl;     // 输出: A
    cout << static_cast<int>(ch) << endl;  // 输出: 65

    4.其他格式化技巧:

    我们需要加上 头文件: #include <iomanip>

    1) 设置小数精度 ;如上

    2) 宽度对齐 & 填充字符

    cout << setw(10) << 42 << endl;         // 宽度为10,默认右对齐
    cout << setfill('*') << setw(10) << 42 << endl;  // 输出:********42

    3)左右对齐

    cout << left << setw(10) << 42 << endl;   // 左对齐
    cout << right << setw(10) << 42 << endl;  // 右对齐

    4) 输出十六进制/八进制

    cout << hex << 255 << endl;  // ff
    cout << oct << 255 << endl;  // 377
    cout << dec << 255 << endl;  // 255 (恢复十进制)

    显示符号位(正数也带 + )

    cout << showpos << 123 << endl;  // +123

    再次理解

    运算符重载是指可以自定义某个类使用某个运算符的逻辑,譬如+,-,*等等。

    而<<这个运算符也是可以被重载的;例如ostream类就是重载了这个运算符 。

    cout是ostream的一个对象,它使用<<能够将数据写入这个缓冲区。

    实际上cout<<10是operator<<(cout, 10);的语法糖。即他本质上是调用了operator<<,并把要打印的东西(整数,浮点数,字符,字符串)作为参数。

    而这个运算符重载函数返回的是ostream&,即引用类型,则他可以实现链式调用;

    版权声明:

    本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

    我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

    热搜词