第二章:数据类型与运算符——C++的“砖块”与“泥瓦匠”
说实话,学编程就像盖房子。数据类型就是砖块,运算符就是泥瓦匠手里的工具。砖块选不对,工具用不好,房子迟早要塌。我在项目里见过太多新手在这上面栽跟头,所以这一章咱们好好捋一捋。
2.1 基本数据类型——C++的“砖块”
C++里有哪些砖块?说白了就是整数、浮点数、字符、布尔值这几种。我习惯把它们分成两类:整型和浮点型。
| 类型 | 关键字 | 大小(通常) | 范围 |
|---|---|---|---|
| 整型 | int | 4字节 | -2^31 ~ 2^31-1 |
| 短整型 | short | 2字节 | -32768 ~ 32767 |
| 长整型 | long | 4或8字节 | 取决于平台 |
| 浮点型 | float | 4字节 | 约±3.4e38 |
| 双精度浮点 | double | 8字节 | 约±1.7e308 |
| 字符型 | char | 1字节 | -128 ~ 127 |
| 布尔型 | bool | 1字节 | true / false |
我的小建议:能用int就别用short,能用double就别用float。为什么?因为现代CPU对int和double的优化做得最好,用short反而可能拖慢速度。我在QT项目里吃过这个亏,后来全改成int了。
2.2 常量与变量——数据的两副面孔
常量就是“死数据”,变量就是“活数据”。你想想看,圆周率π是常量,永远不会变;但用户的年龄是变量,今天18明天就19了。
// 常量定义
const double PI = 3.1415926;
const int MAX_USERS = 1000;
// 变量定义
int age = 25;
double salary = 15000.5;
char grade = 'A';
bool isActive = true;
注意:我曾经在代码里把const写成了#define,结果调试了一下午才发现是宏替换出了问题。记住:C++里尽量用const,别用#define定义常量。
2.3 输入输出——和程序“对话”
输入输出是程序的门面。C++里用cin和cout,简单直接。
#include <iostream>
using namespace std;
int main() {
int number;
cout << "请输入一个整数:";
cin >> number;
cout << "你输入的是:" << number << endl;
return 0;
}
嗯,这里要注意:cin和cout虽然好用,但在QT项目里我更喜欢用QInputDialog和QMessageBox,用户体验更好。不过那是后话了。
2.4 算术运算符——最基础的“工具”
加减乘除,小学就会。但C++里有个坑:整数除法会丢掉小数部分。
int a = 10, b = 3;
cout << a / b; // 输出3,不是3.333
double c = 10.0, d = 3.0;
cout << c / d; // 输出3.33333
避坑指南:我曾经在计算平均分时用了int/int,结果全班平均分全是整数,被老师骂了一顿。记住:只要涉及除法,至少让一个操作数是浮点数。
2.5 关系运算符——比较的艺术
关系运算符就是比大小:>、<、>=、<=、==、!=。结果只有true或false。
int score = 85;
if (score >= 60) {
cout << "及格了";
} else {
cout << "不及格";
}
为什么我要强调这个?因为我在代码审查时发现,很多人把==写成了=,结果条件永远为真。这种bug最难找。
2.6 逻辑运算符——组合判断
逻辑运算符有三个:&&(与)、||(或)、!(非)。说白了就是“并且”、“或者”、“取反”。
int age = 20;
bool hasID = true;
if (age >= 18 && hasID) {
cout << "可以进入";
}
我的经验:逻辑运算符有短路特性。比如a && b,如果a是false,b就不会执行。我利用这个特性写过不少高效代码,但也因此踩过坑——b里如果有函数调用,可能永远不会执行。
2.7 位运算符——底层玩家的玩具
位运算符直接操作二进制位:&、|、^、~、<<、>>。说实话,日常开发用得不多,但在嵌入式、加密、性能优化时是神器。
int flags = 0b1010; // 二进制表示
int mask = 0b0010;
int result = flags & mask; // 取出第二位
cout << result; // 输出2(二进制0010)
我记得在QT里做权限控制时,就用位运算来管理多个开关状态,一个int就能搞定32个权限,比用bool数组快多了。
2.8 类型转换——数据变形记
类型转换分两种:隐式转换和显式转换。隐式转换是编译器偷偷帮你做的,显式转换是你主动要求的。
// 隐式转换
int a = 10;
double b = a; // int自动转成double
// 显式转换(C风格)
double c = 3.14;
int d = (int)c; // 丢掉小数部分
// C++风格
int e = static_cast<int>(c);
警告:我曾经在QT项目里用C风格转换把double转成int,结果精度丢失导致界面显示错位。后来全部改用static_cast,代码清晰多了。记住:C++项目里尽量用static_cast、dynamic_cast这些C++风格的转换。
知识体系总览
下面这张图把本章的知识点串起来了,你一看就明白。
这张图把数据类型、运算符、输入输出、类型转换串在了一起。你想想看,数据类型是基础,运算符是工具,输入输出是交互,类型转换是桥梁。四者缺一不可。
核心总结:数据类型决定了数据的“长相”,运算符决定了数据的“行为”,输入输出让数据和外界“交流”,类型转换让数据能“变形”。把这四样玩透了,C++基础就算打牢了。