C++入门:C++入门:浮点数 & 字符型

开篇暴击:为什么0.1+0.2≠0.3?为什么’A’和65竟是孪生兄弟?准备好揭开编程世界最狡诈的伪装者真面目了吗?让我们直击浮点数与字符型的灵魂深处!


引言:当计算机遇上连续世界

浮点数的奇幻漂流

想象用乐高积木拼出圆周率——这就是浮点数的本质!它们用有限精度逼近无限可能,就像用火柴棒拼出蒙娜丽莎的微笑。

1
float pi = 3.14159;  // 在内存中其实是314159×10⁻⁵的二进制版本

字符的七十二变

每个字符都是穿着ASCII外衣的整型间谍:

1
2
char c = 'A';         // 表面是字母
int secret = c; // 暴露真身:65

一、浮点数的量子世界

1.1 浮点三巨头对比

类型 内存空间 有效数字 典型范围 适用场景
float 4字节 6-7位 ±1.18×10⁻³⁸ ~ ±3.4×10³⁸ 图形坐标
double 8字节 15-16位 ±2.23×10⁻³⁰⁸ ~ ±1.79×10³⁰⁸ 科学计算
long double 16字节 18-19位 ±3.36×10⁻⁴⁹³² ~ ±1.18×10⁴⁹³² 高精度金融

内存结构解密(IEEE 754标准):

1
2
符号位 [1] | 指数位 [8/11] | 尾数位 [23/52]
就像科学计数法的二进制版:(-1)^s × 1.m × 2^(e-127)

1.2 浮点数的七大罪

精度丢失案发现场

1
2
3
float a = 0.1f;
double b = 0.2;
cout << a + b; // 输出0.30000000000000004(不是笔误!)

比较浮点数的正确姿势

1
2
3
bool isEqual(double x, double y) {
return fabs(x - y) < 1e-6; // 设置误差容忍度
}

特殊值禁区

1
2
3
double nan = sqrt(-1.0);    // NaN(非数字)
double inf = 1.0 / 0.0; // ∞(无穷大)
if(isnan(nan)) cout << "逮到一个非法数字!";

二、字符的变形记

2.1 ASCII编码:128个角色的舞台

经典角色速查

  • 0~31:控制字符(如’\n’换行、’\t’制表)
  • 32~126:可打印字符(空格到波浪号)
  • 127:DEL键
  • 128~255:扩展ASCII(因系统而异)

字符整型互换术

1
2
3
char c = 67;            // 67 → 'C'
int ascii = 'Z'; // 90
cout << (char)(ascii+2) // 输出'\'(92对应的字符)

2.2 转义字符:键盘上的暗语者

常用转义符黑话表

  • \n:换行(newline)
  • \t:水平制表
  • \\:反斜杠本尊
  • \":在字符串中显示引号
  • \x41:十六进制表示(’A’)

危险操作示范

1
2
char danger = '\61';    // 八进制61=十进制49 → '1'
cout << "\v正在格式化硬盘..."; // 垂直制表符可能引发终端异常

三、现代C++新增字符类型

3.1 应对全球化浪潮

类型 字节数 编码 字面量前缀 适用场景
char16_t 2 UTF-16 u 基本多语言平面
char32_t 4 UTF-32 U 生僻字/表情符号
wchar_t 2/4 平台相关 L Windows API

使用示例

1
2
3
char16_t chinese = u'汉';
char32_t emoji = U'😊';
wcout << L"宽字符字符串";

3.2 原始字符串(Raw String)妙用

处理正则表达式的救星

1
2
string path = R"(C:\Program Files\V2ray\config.json)";  // 无需转义反斜杠
string regex = R"(\d{3}-\d{4})"; // 匹配电话号码

四、必知必会的六大军规

4.1 浮点数使用守则

  1. 金融计算禁用float/double(用decimal库)
  2. 避免连续浮点运算(误差会累积)
  3. 警惕隐式类型转换:
    1
    2
    int a = 5;
    double b = a / 2; // 结果是2.0!应改为a/2.0

4.2 字符处理雷区

  1. 不要假设char是有符号的:
    1
    char c = 255;  // 可能是-1或255,用uint8_t明确
  2. 慎用C风格字符串:
    1
    char name[20] = "张三"; // 可能溢出,改用string

五、调试利器:三件必备工具

5.1 查看内存二进制

1
2
3
4
float f = 3.5f;
unsigned char* p = (unsigned char*)&f;
for(int i=0; i<4; ++i)
cout << bitset<8>(p[i]) << " "; // 输出IEEE754二进制表示

5.2 数值极限查询

1
2
3
#include <limits>
cout << "float最小值:" << numeric_limits<float>::min();
cout << "char是否有符号?" << numeric_limits<char>::is_signed;

5.3 类型转换检测

1
2
auto type_check = 3.14f;  // 自动推导为float
decltype('A') char_type; // 推导为char

结语:编程世界的两面性

浮点数教会我们接受不完美,字符型展示了表象与本质的辩证关系。当你能优雅处理0.1+0.2的误差,当你看透’A’的整型本质,就真正掌握了计算机世界的语言哲学。下期我们将深入指针迷宫,揭开内存操作的神秘面纱!


🚀 终极挑战

1
2
double magic = 0.0 / 0.0;
cout << (magic == magic) ? "相等" : "不相等"; // 输出什么?

📚 拓展资源

🛠️ 推荐练习

  1. 实现浮点数精确比较模板
  2. 编写ASCII码转换器程序
  3. 测试不同区域设置的字符编码差异