1. 表达式求值 #
int a = 5, b = 2;
double c = 2.0;
a / b * c; // 结果是 4.0(整数除法 5/2=2,2*2.0=4.0)
(double)a / b * c; // 结果是 5.0(5.0/2=2.5,2.5*2.0=5.0)
2. 十进制浮点数上溢流程 #
按照正文的约定,“正规的”坑位是 \( dd × 10^{dd} \) \( 07 \times 10^{21} \) -×10-> \( 07 \times 10^{22} \) -×10-> … -×10-> \( 07 \times 10^{99} \) -> \( 7 \times 10^{100} \)(开始非正规化,丢失精度)→ … → \( 7 \times 10^{999} \) → inf(上溢)
3. x 与 y 的最终取值 #
int x = 0;
bool y = ((x++ == 3) and (x++ == 4));
// x 最终为 1(只有第一个 x++ 执行了,第二个由于短路求值未执行)
// y 为 false(第一个 x++ 返回0,不等于3,短路求值,第二个 x++ 不执行)
警示:不要将多个模糊的操作(如自增、赋值)混在同一表达式中,容易引发逻辑错误。
4. 未定义行为表达式 #
int x = 1;
x = x++ + ++x;
// 这是未定义行为(UB),结果取决于编译器实现。
// 常见编译器(如GCC、MSVC)可能会输出 4,但绝对不可依赖。
// 大学考试中可能会考,但实战中严禁使用。
5. 变量作用域检测 #
程序流:进入 main()-> 进入 test()-> 进入块-> 输出块里面的 x-> 输出全局的 x-> 离开块-> 输出 test() 里的 x-> 离开 test()-> 输出 main() 的 x-> 离开 main()
因此,输出:
30 10 20 10
6. 补码小挑战 #
-
原码:直观表示,但存在“+0”和“-0”问题(如 0000 0000 和 1000 0000 都表示 0)。
-
反码:取反表示负数,但仍存在双零问题。
-
补码:
反码 + 1,解决了双零问题,统一了加减法运算:-
例如:
1 + (-1) = 0000 0001 + 1111 1111 = 1 0000 0000(溢出舍去) = 0 -
范围:-128 ~ 127(8 位有符号 char),更高效且自然。
-
读者可以自己举出更多例子计算(十进制也可以)。