数据类型、引用与auto
C++ 在 C 类型系统上的扩展
在 C 语言数据类型与变量 中,我们学习了int、float、char等基本类型。C++ 完全保留了这些类型,并在此基础上增加了bool、引用、auto等重要特性,同时提供了类型安全的iostream输入输出。
本篇聚焦 C++ 相对 C 的类型与 I/O 扩展;整型、浮点、字符等基础内容请参阅 C 教程。
一、C++ 基本数据类型(回顾与扩展)
1.1 与 C 兼容的基本类型
C++ 支持 C 的所有基本类型:char、short、int、long、float、double等。用法与 C 相同。
详细说明见 C 语言数据类型与变量。
1.2 C++ 特有:bool 类型
C++ 内置布尔类型bool,取值为true或false:
#include<iostream>intmain(){boolisReady=true;boolisEmpty=false;std::cout<<std::boolalpha;// 输出 true/false 而非 1/0std::cout<<"isReady: "<<isReady<<std::endl;std::cout<<"isEmpty: "<<isEmpty<<std::endl;intscore=85;boolpassed=(score>=60);std::cout<<"passed: "<<passed<<std::endl;return0;}| 对比 | C | C++ |
|---|---|---|
| 布尔类型 | 无(用 int 0/1 模拟) | bool,true/false |
| 条件判断 | 非零为真 | 同左,但 bool 语义更清晰 |
二、引用(Reference)
2.1 什么是引用
引用是变量的别名——定义时必须初始化,且之后不能绑定到其他对象:
#include<iostream>intmain(){intoriginal=42;int&ref=original;// ref 是 original 的别名ref=100;std::cout<<"original: "<<original<<std::endl;// 100std::cout<<"ref: "<<ref<<std::endl;// 100return0;}2.2 引用 vs 指针
| 特性 | 引用int& | 指针int* |
|---|---|---|
| 初始化 | 必须初始化 | 可为空(NULL/nullptr) |
| 重新绑定 | 不能 | 可以指向其他对象 |
| 解引用 | 直接使用,无需* | 需要*解引用 |
| 空值 | 不存在空引用 | 可以 nullptr |
| 主要用途 | 函数参数、返回值 | 动态内存、可选值 |
voidswap(int&a,int&b){inttemp=a;a=b;b=temp;}intmain(){intx=1,y=2;swap(x,y);// 直接修改 x、y,无需传地址std::cout<<x<<", "<<y<<std::endl;// 2, 1return0;}指针的完整讲解见 C 语言指针。C++ 中优先用引用传递非空对象,用指针表示可选或动态内存。
2.3 const 引用
不能通过 const 引用修改原对象,常用于函数参数以避免拷贝:
voidprint(conststd::string&s){std::cout<<s<<std::endl;// s = "other"; // 错误:不能修改}三、auto 与类型推导(C++11)
3.1 auto 关键字
编译器根据初始化表达式自动推导类型:
#include<iostream>#include<vector>intmain(){autoi=42;// intautod=3.14;// doubleautos=std::string("hello");// std::stringstd::vector<int>vec={1,2,3};for(autoit=vec.begin();it!=vec.end();++it){std::cout<<*it<<" ";}std::cout<<std::endl;return0;}3.2 使用建议
| 场景 | 是否推荐 auto |
|---|---|
| 迭代器、复杂模板类型 | 推荐 |
| 简单整型、浮点 | 可选,显式类型更清晰 |
| 函数返回值 | 谨慎,需确保可读性 |
3.3 decltype
获取表达式的类型,常用于模板元编程:
intx=0;decltype(x)y=10;// y 的类型与 x 相同,为 int四、const 与 constexpr
4.1 const
与 C 类似,表示只读:
constintMAX_SIZE=100;constdoublePI=3.14159;4.2 constexpr(C++11)
编译期常量,值在编译时确定:
constexprintBUFFER_SIZE=256;constexprintsquare(intn){returnn*n;}intmain(){intarr[square(5)];// 数组大小为 25,编译期确定return0;}五、iostream 输入输出
5.1 标准输出 cout
#include<iostream>intmain(){intage=25;doubleheight=1.75;std::cout<<"年龄:"<<age<<std::endl;std::cout<<"身高:"<<height<<" 米"<<std::endl;return0;}与 printf 对比:
| 特性 | printf | cout |
|---|---|---|
| 类型安全 | 需手动匹配格式符 | 编译期检查 |
| 语法 | printf("%d", x) | cout << x |
| 扩展性 | 固定 | 可重载<< |
5.2 标准输入 cin
#include<iostream>intmain(){inta,b;std::cout<<"请输入两个整数:";std::cin>>a>>b;std::cout<<"和为:"<<a+b<<std::endl;return0;}C 的
scanf/printf在 C++ 中仍可用(#include <cstdio>),但推荐优先使用 iostream。
5.3 常用操纵符
#include<iostream>#include<iomanip>intmain(){doublepi=3.14159265;std::cout<<std::fixed<<std::setprecision(2)<<pi<<std::endl;// 3.14std::cout<<std::boolalpha<<true<<std::endl;// truereturn0;}六、类型大小与 sizeof
与 C 相同,sizeof返回类型或变量占用的字节数:
#include<iostream>intmain(){std::cout<<"sizeof(int): "<<sizeof(int)<<std::endl;std::cout<<"sizeof(bool): "<<sizeof(bool)<<std::endl;std::cout<<"sizeof(double): "<<sizeof(double)<<std::endl;return0;}七、实战练习
练习1:引用交换
编写void swap(int& a, int& b),在 main 中验证交换效果。
练习2:auto 推导
声明多个auto变量,用typeid或编译器推断确认其类型:
#include<typeinfo>#include<iostream>intmain(){autox=10;autoy=3.14;std::cout<<typeid(x).name()<<std::endl;std::cout<<typeid(y).name()<<std::endl;return0;}练习3:iostream 计算器
用cin/cout实现两数加减乘除,对比 C 版scanf/printf的实现。
八、总结与延伸
本节重点回顾
- C++ 保留 C 基本类型,新增bool类型
- 引用是别名,必须初始化,常用于函数参数避免拷贝
- auto让编译器推导类型,简化复杂类型声明
- iostream(cout/cin)提供类型安全的 I/O,推荐替代 printf/scanf
- constexpr用于编译期常量与函数
下节预告
下一篇将进入核心语法阶段:《运算符与表达式:C++ 扩展特性》,学习 new/delete 等 C++ 运算符。
延伸阅读
- C 语言数据类型与变量
- C 语言指针
- C++ 速查:数据类型与引用
📌知识点卡片
- bool:
true/false;引用T&必须初始化,是别名 - auto:编译期类型推导;const 引用
const T&用于只读参数 - 输出:
std::cout << x << std::endl;输入:std::cin >> x - C 基础类型用法见 C 教程;C++ 增量重点在引用、bool、iostream
💡小技巧
- 函数参数中,大对象用
const T&传递,避免拷贝 - 简单循环变量可写
for (auto i = 0; i < n; ++i)
⚠️注意事项
- 引用必须初始化,不能为空
- 不要返回局部变量的引用或指针(悬垂引用)
- 混用 cout 与 printf 时注意缓冲区刷新
如果你对数据类型与引用有疑问,欢迎在评论区留言!下一篇见!