第一个程序与输入输出

建议先阅读:02_环境配置

原理

main 是 C++ 程序的唯一入口点——操作系统加载可执行文件后,C 运行时(crt0)调用 main 函数。return 0 将退出码传给操作系统(约定 0=成功,非 0=异常)。

#include <iostream>
 
int main() {
 std::cout << "Hello, World!" << std::endl;
 return 0;
}
```asm
 
**预处理阶段**:`#include <iostream>` 将整个 `iostream` 头文件内容插入此处。`<iostream>` 包含约 2-3 万行模板代码,这也是预处理后文件膨胀的原因。
 
**内存中的 I/O**:`std::cout` 是全局 `std::ostream` 对象,通过 `<<` 运算符重载将数据写入**输出缓冲区**。缓冲区满或遇 `std::endl`/`std::flush` 时才真正写入控制台(系统调用 `write()`),这也是缓冲区存在的性能意义。
 
`std::cin` 是 `std::istream` 对象,从**输入缓冲区**读取数据。`cin >> x` 以空白字符(空格/Tab/换行)为分隔符,自动跳过前导空白。剩余换行符留在缓冲区中——这是 `cin >>` 后接 `getline` 需要 `cin.ignore()` 的原因。
 
> `std::endl` = `'\n'` + `flush()`;`'\n'` 仅输出换行,不刷新。高频输出用 `'\n'` 性能更好。
 
### cout 与 printf 的底层差异
 
- `printf` 依赖格式字符串(`%d`, `%f` 等),类型不匹配是**未定义行为**——编译器不检查
- `cout` 通过运算符重载实现类型安全,编译器自动选择正确的 `<<` 重载
- `std::ios::sync_with_stdio(false)` 可关闭 cout 与 printf 的同步,提升 cin/cout 速度
 
---
 
## 语法
 
### 基本输入输出
 
```cpp
#include <iostream>
#include <string>
 
int main() {
 int a, b;
 std::cin >> a >> b;
 std::cout << a + b << std::endl;
 
 std::string line;
 std::cin.ignore(); // 清除残留换行符
 std::getline(std::cin, line); // 读取整行
 std::cout << line << '\n';
 
 return 0;
}
```cpp
 
### 格式化输出
 
```cpp
#include <iostream>
#include <iomanip>
 
int main() {
 double pi = 3.141592653589793;
 
 std::cout << std::setprecision(3) << pi << '\n'; // 3.14 (有效数字)
 std::cout << std::fixed << std::setprecision(3) << pi << '\n'; // 3.142 (小数位)
 
 std::cout << std::setw(10) << std::right << "Hello" << '\n';
 std::cout << std::setfill('0') << std::setw(8) << 42 << '\n';
 
 int n = 255;
 std::cout << std::hex << std::showbase << std::uppercase << n << '\n'; // 0XFF
 std::cout << std::oct << n << '\n'; // 377
 std::cout << std::dec << n << '\n'; // 255
}
```asm
 
| 操控器 | 作用 | 持续性 |
|--------|------|--------|
| `setw(n)` | 宽度 | 仅下一次 |
| `setprecision(n)` | 精度 | 持续 |
| `fixed` | 定点小数 | 持续 |
| `setfill(c)` | 填充字符 | 持续 |
| `left`/`right` | 对齐 | 持续 |
| `hex`/`oct`/`dec` | 进制 | 持续 |
 
### main 函数签名
 
```cpp
int main() { return 0; } // 无参数
int main(int argc, char* argv[]) { return 0; } // 命令行参数
```cpp
`argc` 是参数个数(含程序名本身),`argv` 是参数字符串数组。
 
---
 
## 实践
 
cin-getline 混用陷阱:
```cpp
int n;
std::cin >> n;
std::cin.ignore(); // 必须清除缓冲区的换行符
std::string s;
std::getline(std::cin, s);
```cpp
 
> `cin.fail()` 检测输入失败;`cin.clear()` 清除错误标志;`cin.ignore()` 丢弃缓冲区字符。
 
练习 I/O 练习:
练习: 入门练习
练习: 简单计算题
练习: 简单输入输出题