🔷 第二章 C++语言基础
📄 一句话概括

数值类型 = 整型 + 浮点。选型只需要记住四条:日常整数用 int;装大数(金额分、时间戳、ID)用 long long;小数用 double;确定非负且要省内存才考虑 unsigned(但要小心减法)。另外记住一个不可靠因素:long 在 Windows 是 4 字节、在 64 位 Linux 是 8 字节——要 8 字节就明确写 long long。

一、完整对照表

类型 字节 大致范围 什么时候用
short 2 −3.2 万 ~ 3.2 万 大数组、嵌入式(省内存)
int 4 −21.4 亿 ~ 21.4 亿 默认选择
unsigned int 4 0 ~ 42.9 亿 一定非负的计数(减法要小心)
long 4 或 8 视平台 ⚠ 不可靠,跨平台别用
long long 8 −922 京 ~ 922 京 金额、时间戳、大 ID
float 4 约 7 位有效数字 内存吃紧时降级
double 8 约 15~16 位有效数字 小数首选
long double 10/12/16 更高 极少用

这张表要"背"的只有三个数字:int 4 字节、long long 8 字节、double 8 字节。

二、类型修饰符怎么组合

signed short int a;          // 可以简写为 short(signed 默认就有)
unsigned int b;              // 简写 unsigned
unsigned long long c;        // 无符号超长整型

组合规则:signed/unsigned(有没有负数)× short/long/long long(多宽)× 基础类型。入门只需要记住 int、unsigned、long long 三种写法,其余用到再查。

三、混算的时候按谁算

不同类型放一起运算,编译器会把"小的"升级成"大的":

cout << 5 / 2 << endl;          // 2     两个 int → 整数除法
cout << 5 / 2.0 << endl;        // 2.5   有一个 double → 按浮点算
cout << 5.0 / 2 << endl;        // 2.5   同上

int a = 5;
double b = 2;
cout << a / b << endl;          // 2.5   整数被提升为 double 再除

升级的大致方向:char/short → int → long long → float → double。

关键结论:想要小数结果,参与运算的至少得有一个是浮点——写 5 / 2 永远得 2,写成 5 / 2.0 才有 2.5。这是新手算错题的头号原因。

四、查范围用什么

#include <climits>          // 整型范围:INT_MAX、SHRT_MAX、LLONG_MAX…
#include <cfloat>           // 浮点范围:FLT_MAX、DBL_MAX…(还有 FLT_DIG 表示有效位数)

cout << INT_MAX << endl;        // 2147483647
cout << LLONG_MAX << endl;      // 9223372036854775807

背不住数字没关系,记住"有这两个头文件可以查"就够了。代码里不要硬编码这些数字(比如写 if (n > 2147483647)),用 INT_MAX 更清晰也更安全。

五、动手 Demo:混算与类型提升

新建 numeric.cpp:

#include <iostream>
#include <climits>
using namespace std;

int main() {
    cout << "5 / 2     = " << 5 / 2     << endl;    // 2
    cout << "5 / 2.0   = " << 5 / 2.0   << endl;    // 2.5
    cout << "5 % 2     = " << 5 % 2     << endl;    // 1(取余,只能用于整数)

    int a = 7, b = 2;
    double avg = a / b;                             // ⚠ 先算整数除法,再存
    cout << "错误平均分 = " << avg << endl;          // 3(不是 3.5)

    double rightAvg = (double)a / b;                // 先转成 double 再除
    cout << "正确平均分 = " << rightAvg << endl;     // 3.5

    cout << "INT_MAX = " << INT_MAX << endl;
    return 0;
}

看到什么算成功:能看到 错误平均分 = 3 与 正确平均分 = 3.5 的巨大差别。

这就是本节最实用的一条知识:"先算完再存"。double avg = a / b; 里,除法已经按整数做完了(结果 3),存进 double 也救不回来。修法是把其中一个先转成 double(第 3 章讲强制类型转换)。

30 秒实验:把 int a = 7; 改成 int a = 8;,错误版和正确版都变成 4.0 与 4.0——这时候错误被掩盖了。这正是"隐形 bug"的典型:只在除不尽时才露头。

六、常见误区

  1. "int 包打天下"——手机号、金额"分"、时间戳都会超过 21 亿。先想清楚量级,再选类型
  2. "unsigned 更安全,因为没有负数"——正好相反:unsigned u = 0; u - 1; 会变成 42.9 亿。新手不确定就别用
  3. "long 和 long long 差不多"——在 Windows 上 long 只有 4 字节,和 int 一样。要更大就写 long long,别用 long 赌
  4. "double avg = a / b; 会按小数除"——不会。除法在赋给 double 之前就按整数算完了。要小数结果,必须先转换其中一个操作数
自测四问(点开对答案) 1. 日常整数、金额、小数分别该用什么类型?——整数用 `int`;金额用 `long long`(以"分"计);小数用 `double`。 2. `int a = 7, b = 2; double x = a / b;` 结果是多少?为什么?——**3.0**;因为除法先按**整数**算得 3,再转成 double。 3. `5 / 2` 想得到 2.5 该怎么写?——让其中一个操作数是浮点:`5 / 2.0`、`5.0 / 2` 或 `(double)5 / 2`。 4. 为什么说 `long` 不可靠?——它在 Windows 上是 4 字节、在 64 位 Linux 上是 8 字节,**跨平台结果可能不同**;要 8 字节写 `long long`。

相关笔记