一、C++ 的输入与输出
在 C 语言中,我们主要依赖 和 函数完成输入输出,需要手动指定格式符并处理类型不匹配的风险。C++ 引入了全新的 IO 流库,以类型安全和可扩展的设计重构了输入输出体验。
一、C++ 的输入与输出 在 C 语言中,我们主要依赖 printf 和 scanf 函数完成输入输出,需要手动指定格式符并处理类型不匹配的风险。C++ 引入了全新的 IO 流库,以类型安全和可扩展的设计重构了输入输出体验。 1.1 核心载体:<iostream> 头文件 <iostream> 是 **Input Output Stream** 的缩写,为 C++ 标准输入输出的核心头文件。它不仅…

在 C 语言中,我们主要依赖 和 函数完成输入输出,需要手动指定格式符并处理类型不匹配的风险。C++ 引入了全新的 IO 流库,以类型安全和可扩展的设计重构了输入输出体验。
printfscanf<iostream> 头文件<iostream> 是 Input Output Stream 的缩写,为 C++ 标准输入输出的核心头文件。它不仅定义了 cin、cout、endl 等标准 IO 对象,还封装了底层 IO 操作的复杂逻辑,使开发者无需关注缓冲区管理与设备交互等细节。
注意:在 Visual Studio(微软编译器)中,
<iostream>会间接包含<stdio.h>,因此允许混用cin与scanf。但这并非 C++ 标准行为,跨平台兼容性较差,实际开发中应避免混用。
cin 与 coutstd::cin 标准输入流std::cin 是 istream 类的对象,主要面向窄字符(char 类型)的标准输入流。它从键盘或其他输入设备获取数据,通过流提取运算符 >> 完成数据读取。
#include <iostream>
int main() {
int age;
std::cout << "请输入你的年龄:";
std::cin >> age; // 从标准输入读取整数
std::cout << "你的年龄是:" << age << "岁" << std::endl;
return 0;
}
std::cout 标准输出流std::cout 是 ostream 类的对象,同样是面向窄字符的标准输出流。它通过流插入运算符 << 向屏幕或其他输出设备写入数据,支持链式调用。
#include <iostream>
int main() {
std::cout << "Hello, C++ IO Stream!" << std::endl;
return 0;
}
<< 与 >> 的双重身份在 C 语言中,<< 与 >> 分别代表左移和右移运算符。C++ 通过运算符重载技术赋予了它们新的角色:
<<:流插入运算符,用于向输出流写入数据。>>:流提取运算符,用于从输入流提取数据。这种重载实现了语法糖效果,使 IO 操作更符合直觉。运算符的返回值是流对象本身的引用,因此支持链式调用:
std::cout << "姓名:" << "张三" << ",年龄:" << 25 << std::endl;
底层原理:每次 << 操作返回 ostream&,使后续操作可直接作用于同一个流对象。
endl 的应用std::endl 的作用不仅是换行:
\n,实现文本换行。与直接使用 \n 的区别:
// 仅换行,不刷新缓冲区,性能更优
std::cout << "Hello\n";
// 换行 + 刷新缓冲区,适用于需要立即输出的场景(如调试日志)
std::cout << "Hello" << std::endl;
最佳实践:频繁使用
endl会导致缓冲区频繁刷新,降低 IO 性能。在对性能敏感的场景中,应优先使用\n,仅在需要立即输出时使用endl。
C 语言的 printf() 需要手动指定格式符(如 %d、%f),格式符与变量类型不匹配会导致未定义行为。C++ IO 流通过函数重载实现了自动类型识别:
int num = 42;
double pi = 3.14;
std::string name = "C++";
std::cout << num << " " << pi << " " << name << std::endl; // 自动识别类型,输出:42 3.14 C++
该设计简化了代码,并从根本上避免了格式不匹配问题。
C++ IO 流支持自定义类型的输入输出。通过重载 << 和 >> 运算符,可使自定义类/结构体像内置类型一样参与 IO 操作:
#include <iostream>
struct Point {
int x, y;
};
// 重载 << 运算符,实现 Point 类型的输出
std::ostream& operator<<(std::ostream& os, const Point& p) {
return os << "(" << p.x << ", " << p.y << ")";
}
int main() {
Point p{10, 20};
std::cout << "点的坐标:" << p << std::endl; // 输出:点的坐标:(10, 20)
return 0;
}
这种可扩展性使 C++ IO 流成为面向对象编程的理想选择。
C++ IO 流的设计深度融合了面向对象的核心思想:
istream 和 ostream 作为基类,派生出文件流(fstream)、字符串流(stringstream)等子类,实现了 IO 操作的统一接口。这些设计使 IO 流库既灵活又易于扩展,但也要求开发者掌握一定的面向对象知识以深入理解其底层原理。
在需要高性能 IO 的场景中,C++ 默认流可能不如 C 语言高效。可通过以下代码关闭 C++ 流与 C 标准 IO 的同步,并解除 cin/cout 的绑定,从而大幅提升效率:
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
缺省参数(默认参数)是指在声明或定义函数时为参数指定一个默认值。调用函数时,若未传递实参,则使用缺省值;若传递了实参,则使用实参值。
#include <iostream>
void Func(int a = 10) {
std::cout << a << std::endl;
}
int main() {
int a = 20;
Func(a); // 传入实参,输出 20
Func(); // 未传实参,使用缺省值,输出 10
return 0;
}
全缺省指函数的所有参数均提供缺省值。
void Func(int a = 10, int b = 20, int c = 30) {
std::cout << a << " " << b << " " << c << std::endl;
}
调用时可传递全部、部分或不传递参数。但 C++ 规定实参必须从左到右依次传递,不能跳跃传递。例如 Func(a, , c) 是非法的。若需跳过中间参数,可通过调整参数顺序实现:
void Func(int a = 10, int c = 30, int b = 20) {
std::cout << a << " " << b << " " << c << std::endl;
}
// 调用 Func(a, c) 即可分别指定 a 和 c 的值
半缺省指仅对部分参数提供缺省值。C++ 规定缺省参数必须从右向左连续给出,不能间隔跳跃。
// 正确:仅缺省最后一个参数
void Func(int a, int b, int c = 10);
// 正确:缺省后两个参数
void Func(int a, int b = 20, int c = 10);
// 错误:缺省参数不连续
// void Func(int a = 10, int b, int c = 20);
注意:
- 调用带缺省参数的函数时,实参必须从左到右依次给出。
- 若函数声明与定义分离,缺省参数只能在声明处指定,定义处不能再重复指定,否则会导致重定义错误。
在 C 语言中,功能相似但参数类型不同的函数必须使用不同的名称,降低了开发效率。C++ 引入函数重载机制解决了这一问题。
C++ 允许在同一作用域内声明多个同名函数,但要求它们的形参列表不同(参数个数不同、参数类型不同或参数类型顺序不同)。函数调用时,编译器会根据实参类型自动匹配最合适的函数,体现了多态性。C 语言不支持同一作用域内的同名函数。
#include <iostream>
// 参数类型不同
int add(int a, int b) {
std::cout << "int (a+b) " << a + b << std::endl;
return a + b;
}
double add(double a, double b) {
std::cout << "double (a+b) " << a + b << std::endl;
return a + b;
}
// 参数个数不同
int add(int a, int b, int c) {
std::cout << "int (a+b+c) " << a + b + c << std::endl;
return a + b + c;
}
// 参数类型顺序不同
void print(int a, double b) { std::cout << "int, double" << std::endl; }
void print(double a, int b) { std::cout << "double, int" << std::endl; }
int main() {
add(10, 20);
add(1.2, 2.2);
add(10, 20, 30);
print(10, 2.2);
print(1.2, 20);
return 0;
}
重要规则:
- 返回值类型不能作为重载依据。编译器无法仅凭返回值区分调用哪个函数,以下代码会编译报错:
int fxx(); void fxx(); // 错误:仅返回值不同,无法重载- 注意缺省参数与重载的冲突。若重载函数因缺省参数导致调用时产生二义性,编译器将报错:
void fxx(int a); void fxx(); // 若调用 fxx(),编译器无法确定是调用无参版本,还是调用带缺省参数的版本(若存在)

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online