C++ JOURNAL / 我的易错记录
我最容易写错的地方
不是一次记住所有规则,而是下次遇到时知道去哪里找。
按我的学习记录整理 · 示例用于帮助理解这篇记录里
这些是从我的学习疑问和实际错误中整理的提醒。不是对学习能力的评价,也不是要求一次全部记住。
运算符:看起来只差一点
- = 和 ==:赋值用 =,比较相等用 ==。条件里赋值有时能编译,因此不能只看是否报错。
- << 和 >>:cout << 是输出;cin >> 是输入。我曾把 cout 写成 cout >> i。
- % 和 /:% 求余数,/ 做除法。非负整数 n % 10 取个位,n / 10 去个位。
- n % i = 0 和 n % i == 0:判断整除要比较余数是否为 0,不能给取余表达式赋值。
相关:运算与数字拆分。
分号、条件与循环边界
- else 后面多一个 ;:空语句成为 else 的内容,后面的 y = x * x 会继续执行。我因此把 x = 0.5 的平方根覆盖成了 0.25。
- for 后面多一个 ;:得到空循环体,后面的代码不属于这个循环。
- i < n 和 i <= n:先看从几开始、是否包含 n。从 0 开始执行 n 次,通常用 i < n。
- 数组下标从 0 开始:int a[10] 只能访问 a[0] 到 a[9]。
- else if 条件范围:区间写 x >= 0 && x <= 1,不能直接写数学式 0 <= x <= 1。
- for 的三个部分:初始化只做一次;条件每轮进入前检查;自增在循环体之后执行。
- i++ 的分号:单独语句 i++; 是对的。for 括号第三部分后不能再随意加分号;for (...) 后的分号又是另一回事。
- 变量初值:约数题从 i = 1 开始,不能只声明 int i 就直接拿来比较、取余。
类型不是只有“能装进去”这么简单
- char 和 int:'a' 是字符,97 是整数。常见编码下有关联,但不是同一类型。
- string 和 %s:一个是 C++ 类型,一个是 C 格式说明符,不能直接替换。
- int 和 long long:范围不同。结果变量写成 long long,不保证右边的 int 运算不溢出。
- signed 和 unsigned:是否能表示负数、范围都不同,不随意互换。
- 强制转换:cin >> (char)a 不能作为字符输入。要定义 char 变量再读入;(int)b 也可能改变大整数的值。
- L 与 long long:L 是常量后缀,不是变量声明;要区分 L 与 LL。
相关:类型与整数范围。
输入输出:格式也是题目的一部分
- hex 和 dec:影响对应流中的整数进制,设置会保留;需要十进制就切回 dec。
- setw 的范围:这里通常只设置下一项的最小宽度,不会自动套用到所有后续输出。
- fixed + setprecision:一起使用才表示这里的小数点后位数;printf 的写法另算。
- printf 的数量与类型:四个占位符不能只传一个参数,每一项类型也要对应。
- cin >> string 与逗号:空白是分隔符,逗号不是,不能指望它自动停在逗号前。
- %lf.2 与 %.2f:保留两位小数要把 .2 放在 f 前面,不是输出以后补一个 .2。
相关:C++ 输入输出格式、C 格式补充。
题目里的数学表达式
- f(x) 和 f(f(x)):先求里面,再把结果作为参数求外面,不能漏掉第二次调用。
- sqrt(x):平方根写函数调用,并包含 cmath;不能直接照抄纸上的根号。
遇到 0、2、7871 这样的意外结果,先回到调试与排错记录,不要只凭一个数字猜原因。