【C++基础与提高】第二章:C++数据类型系统——构建程序的基础砖石
【C++基础与提高】第二章:C++数据类型系统——构建程序的基础砖石
(持续更新中,欢迎关注!)
文章目录
- 【C++基础与提高】第二章:C++数据类型系统——构建程序的基础砖石
- 2.1 数据类型概述——为什么需要不同类型?
- 2.2 基本数据类型——C++的原子构件
- 2.2.1 整数类型详解
- 2.2.2 浮点类型——处理小数的利器
- 2.2.3 字符类型——文字世界的通行证
- 2.2.4 布尔类型——逻辑判断的核心
- 2.3 复合数据类型——构建复杂数据结构
- 2.3.1 数组——有序数据集合
- 2.3.2 结构体——自定义数据类型
- 2.4 类型修饰符——精细化控制内存使用
- 2.5 类型推导——让编译器帮你思考
- 2.6 类型转换——不同类型间的桥梁
- 2.6.1 隐式类型转换
- 2.6.2 显式类型转换
- 2.7 内存占用与对齐——深入了解底层机制
- 2.8 最佳实践建议
- 2.9 本章小结
2.1 数据类型概述——为什么需要不同类型?
在现实世界中,我们需要不同的容器来存储不同类型的物品:用水杯装水,用书包装书,用钱包装钱。同样,在编程世界里,我们也需要不同类型的数据类型来存储和处理各种信息。
C++的数据类型就像程序员的工具箱,每种工具都有其特定用途:
- 整数类型用于计数和索引
- 浮点类型用于科学计算
- 字符类型用于文本处理
- 布尔类型用于逻辑判断
2.2 基本数据类型——C++的原子构件
2.2.1 整数类型详解
整数类型是C++中最常用的类型之一,用于存储没有小数部分的数值。
#include <iostream>
#include <climits> // 包含整数类型范围常量int main() {// 不同大小的整数类型short s = 32767; // 通常16位,范围:-32768到32767int i = 2147483647; // 通常32位,范围:-2,147,483,648到2,147,483,647long l = 2147483647L; // 至少32位long long ll = 9223372036854775807LL; // 至少64位std::cout << "short最大值: " << SHRT_MAX << std::endl;std::cout << "int最大值: " << INT_MAX << std::endl;std::cout << "long最大值: " << LONG_MAX << std::endl;std::cout << "long long最大值: " << LLONG_MAX << std::endl;return 0;
}
有符号 vs 无符号整数:
// 有符号整数(可正可负)
int signed_num = -100;
// 无符号整数(只能为正,包括0)
unsigned int unsigned_num = 100U;std::cout << "有符号数: " << signed_num << std::endl; // 输出: -100
std::cout << "无符号数: " << unsigned_num << std::endl; // 输出: 100
2.2.2 浮点类型——处理小数的利器
浮点类型用于表示带有小数部分的实数:
#include <iostream>
#include <iomanip> // 用于控制输出格式int main() {float f = 3.14159f; // 单精度浮点数,约7位有效数字double d = 3.141592653589793; // 双精度浮点数,约15位有效数字long double ld = 3.141592653589793238L; // 扩展精度浮点数std::cout << std::fixed << std::setprecision(10);std::cout << "float: " << f << std::endl;std::cout << "double: " << d << std::endl;std::cout << "long double: " << ld << std::endl;return 0;
}
2.2.3 字符类型——文字世界的通行证
字符类型用于存储单个字符:
#include <iostream>int main() {char c1 = 'A'; // 普通字符char c2 = 65; // ASCII码值char c3 = '\n'; // 转义字符(换行)wchar_t wc = L'中'; // 宽字符,支持Unicodestd::cout << "字符1: " << c1 << std::endl; // 输出: Astd::cout << "字符2: " << c2 << std::endl; // 输出: Astd::cout << "换行前";std::cout << c3; // 换行std::cout << "换行后" << std::endl;return 0;
}
常见转义字符:
\n- 换行\t- 制表符- [\](file://f:\华为攻城狮带你10天搞定C++\c++基础与提高.pdf) - 反斜杠
\'- 单引号\"- 双引号
2.2.4 布尔类型——逻辑判断的核心
布尔类型只有两个值:true(真)和false(假):
#include <iostream>int main() {bool is_raining = true;bool is_sunny = false;std::cout << std::boolalpha; // 以文字形式输出布尔值std::cout << "今天下雨吗? " << is_raining << std::endl; // 输出: truestd::cout << "今天晴天吗? " << is_sunny << std::endl; // 输出: false// 布尔表达式int a = 10, b = 20;std::cout << "a > b ? " << (a > b) << std::endl; // 输出: falsestd::cout << "a < b ? " << (a < b) << std::endl; // 输出: truereturn 0;
}
2.3 复合数据类型——构建复杂数据结构
2.3.1 数组——有序数据集合
数组是一系列相同类型元素的集合:
#include <iostream>int main() {// 声明和初始化数组int numbers[5] = {1, 2, 3, 4, 5}; // 固定大小数组char name[] = "C++"; // 字符数组(字符串)// 访问数组元素(索引从0开始)std::cout << "第一个数字: " << numbers[0] << std::endl; // 输出: 1std::cout << "最后一个数字: " << numbers[4] << std::endl; // 输出: 5// 修改数组元素numbers[2] = 100;std::cout << "修改后的第三个数字: " << numbers[2] << std::endl; // 输出: 100// 遍历数组for(int i = 0; i < 5; i++) {std::cout << "numbers[" << i << "] = " << numbers[i] << std::endl;}return 0;
}
2.3.2 结构体——自定义数据类型
结构体允许我们将不同类型的数据组合在一起:
#include <iostream>
#include <string>// 定义结构体
struct Student {std::string name;int age;double score;bool is_graduate;
};int main() {// 创建结构体变量Student stu1 = {"张三", 20, 85.5, false};// 访问结构体成员std::cout << "学生姓名: " << stu1.name << std::endl;std::cout << "学生年龄: " << stu1.age << std::endl;std::cout << "学生成绩: " << stu1.score << std::endl;std::cout << "是否毕业: " << (stu1.is_graduate ? "是" : "否") << std::endl;// 修改结构体成员stu1.age = 21;std::cout << "一年后年龄: " << stu1.age << std::endl;return 0;
}
2.4 类型修饰符——精细化控制内存使用
C++提供了多种类型修饰符来更精确地控制数据存储:
#include <iostream>int main() {// signed - 有符号(默认)signed int si = -100;// unsigned - 无符号unsigned int ui = 100U;// short - 短整型short sh = 32767;// long - 长整型long lo = 2147483647L;// long long - 更长整型long long ll = 9223372036854775807LL;std::cout << "sizeof(short): " << sizeof(sh) << " bytes" << std::endl;std::cout << "sizeof(int): " << sizeof(si) << " bytes" << std::endl;std::cout << "sizeof(long): " << sizeof(lo) << " bytes" << std::endl;std::cout << "sizeof(long long): " << sizeof(ll) << " bytes" << std::endl;return 0;
}
2.5 类型推导——让编译器帮你思考
现代C++引入了自动类型推导功能,简化代码编写:
#include <iostream>
#include <typeinfo> // 用于获取类型信息int main() {// auto关键字 - 自动推导类型auto x = 42; // 推导为intauto y = 3.14; // 推导为doubleauto z = "Hello"; // 推导为const char*std::cout << "x的类型: " << typeid(x).name() << std::endl;std::cout << "y的类型: " << typeid(y).name() << std::endl;std::cout << "z的类型: " << typeid(z).name() << std::endl;// decltype关键字 - 获取表达式的类型int a = 10;decltype(a) b = 20; // b的类型与a相同,都是intstd::cout << "a + b = " << (a + b) << std::endl;return 0;
}
2.6 类型转换——不同类型间的桥梁
2.6.1 隐式类型转换
#include <iostream>int main() {int i = 100;double d = i; // int自动转换为doublestd::cout << "int to double: " << d << std::endl; // 输出: 100// 混合运算中的类型转换int a = 10;double b = 3.0;double result = a / b; // int先转换为double再运算std::cout << "10 / 3.0 = " << result << std::endl; // 输出: 3.33333return 0;
}
2.6.2 显式类型转换
#include <iostream>int main() {// C风格强制类型转换double pi = 3.14159;int int_pi = (int)pi; // 转换为整数,丢失小数部分// C++风格强制类型转换int int_pi2 = static_cast<int>(pi);std::cout << "原始值: " << pi << std::endl; // 输出: 3.14159std::cout << "转换后: " << int_pi << std::endl; // 输出: 3// 注意潜在的问题unsigned int large_uint = 4000000000U;int negative_int = static_cast<int>(large_uint);std::cout << "大无符号数: " << large_uint << std::endl;std::cout << "转换为有符号: " << negative_int << std::endl;return 0;
}
2.7 内存占用与对齐——深入了解底层机制
不同类型在内存中的占用情况:
#include <iostream>struct Example1 {char c; // 1字节int i; // 4字节short s; // 2字节
};struct Example2 {char c; // 1字节short s; // 2字节int i; // 4字节
};int main() {std::cout << "char大小: " << sizeof(char) << " 字节" << std::endl;std::cout << "int大小: " << sizeof(int) << " 字节" << std::endl;std::cout << "double大小: " << sizeof(double) << " 字节" << std::endl;std::cout << "Example1大小: " << sizeof(Example1) << " 字节" << std::endl;std::cout << "Example2大小: " << sizeof(Example2) << " 字节" << std::endl;return 0;
}
2.8 最佳实践建议
-
选择合适的数据类型
- 根据数据范围选择合适的整数类型
- 对于财务计算优先使用整数避免浮点误差
- 字符串处理优先考虑std::string而非字符数组
-
注意边界条件
// 错误示例:溢出风险 short small_num = 32767; small_num++; // 溢出!// 正确做法:选择合适类型 int larger_num = 32767; larger_num++; -
合理使用类型推导
// 清晰明确的情况 auto result = calculate_something();// 可能引起混淆的情况,建议显式声明 auto value = get_unknown_type(); // 不推荐 SpecificType value = get_unknown_type(); // 推荐
2.9 本章小结
本章详细介绍了C++的数据类型系统,涵盖了:
- 基本数据类型的特点和使用场景
- 复合数据类型的定义和操作
- 类型修饰符的作用和应用
- 类型推导和转换机制
- 内存布局和对齐原则
掌握这些基础知识对于编写高效、安全的C++程序至关重要。下一章我们将深入探讨变量和常量的使用,包括作用域、生命周期等重要概念。
专栏预告:第三章将详细介绍变量与常量的概念,探讨作用域、存储类别以及命名规范等内容,帮助读者建立良好的编程习惯。
