C++ Programming Language —— 第2章:数据类型
目录
1.整型
①含义与作用
②语法格式
③语法示例
④无符号整型(Unsigned)
⑤例题与应用
例题 1:计算圆的周长
例题 2:循环计数器
例题 3:无符号整型的溢出
2.sizeof关键字
①含义
②作用
③语法格式
④基本数据类型的sizeof结果
⑤数组与指针的sizeof
⑥结构体与类的sizeof
⑦函数参数中的数组
⑧例题
例题 1:计算数组元素个数
例题 2:结构体的内存布局
例题 3:动态内存分配
3.实型
①实型的含义与作用
②实型的分类与语法格式
③实型的字面值与精度控制
④实型的运算与注意事项
⑤例题与代码示例
例 1:计算圆的面积
例 2:温度转换(华氏→摄氏)
例 3:高精度计算
⑥实型的优缺点
4.字符型
①基本字符型:char
②含义
③作用
④语法格式
⑤字符与整数的关系
⑥扩展字符类型
⑦字符输入输出
⑧例题与应用
例题 1:统计字符串中的字母数
例题 2:大小写转换
例题 3:判断字符类型
⑨注意事项
5.转义字符
①含义
②作用
③语法格式
④例题
例 1:换行符的使用
例 2:制表符的使用
6.字符串类型
①C 风格
(1)含义
(2)作用
(3)语法格式
(4)注意事项
②C++ 标准库的string类
(1)含义
(2)作用
(3)语法格式
(4)常用成员函数
(5)例题与应用场景
例题 1:C 风格字符串操作
例题 2:string类的应用
③C 风格字符串与string类的对比
7.布尔类型
①含义与作用
②语法格式
③布尔字面量
④布尔表达式
⑤隐式类型转换
⑥示例代码
⑦注意事项
8.数据的输入与输出
①标准输入输出流
②输出操作(使用 cout)
③输入操作(使用 cin)
④格式化输入输出
④文件输入输出
⑤注意事项
1.整型
①含义与作用
- 含义:整型是用于存储没有小数部分的数值类型。
- 作用:
- 作为程序中的计数器、索引或循环变量。
- 存储逻辑判断的结果(如
0
表示假,非零表示真)。 - 处理数学运算中的整数操作。
②语法格式
C++ 提供了多种整型类型,不同类型的存储空间和取值范围不同:
③语法示例
bool isStudent = true; // 布尔型
char grade = 'A'; // 字符型(存储ASCII值)
short age = 25; // 短整型
int count = 100; // 整型
long population = 1000000L; // 长整型(需加后缀L)
long long distance = 9223372036854775807LL; // 超长整型(需加后缀LL)
④无符号整型(Unsigned)
- 作用:存储非负整数,扩大正数的表示范围。
- 语法:在类型前加
unsigned
关键字。
示例:
unsigned int score = 95; // 无符号整型
⑤例题与应用
例题 1:计算圆的周长
#include <iostream>
using namespace std;int main() {const int radius = 5; // 定义常量半径const double PI = 3.14159; // 定义常量πdouble circumference = 2 * PI * radius; // 计算周长cout << "圆的周长是: " << circumference << endl;//圆的周长是: 31.4159return 0;
}
例题 2:循环计数器
#include <iostream>
using namespace std;int main() {for (int i = 0; i < 5; i++) { // 使用int作为计数器cout << "循环次数: " << i << endl;}return 0;
}
//循环次数: 0
//循环次数 : 1
//循环次数 : 2
//循环次数 : 3
//循环次数 : 4
例题 3:无符号整型的溢出
#include <iostream>
using namespace std;int main() {unsigned int num = 4294967295; // 最大值cout << "初始值: " << num << endl;num = num + 1; // 溢出cout << "溢出后的值: " << num << endl; // 输出0return 0;
}
//初始值: 4294967295
//溢出后的值 : 0
2.sizeof关键字
①含义
在 C++ 里,sizeof
是一个编译时一元运算符。借助它,能够计算出一个数据类型或者表达式所占用的内存字节数。sizeof
会在编译阶段就得出结果,不会在程序运行时执行。
②作用
- 内存分配:在使用
new
或者malloc
进行动态内存分配时,sizeof
能帮忙确定所需的内存大小。 - 数组操作:可以利用
sizeof
计算数组的元素数量,不过要注意这种方式不适用于函数参数中的数组。 - 平台适配:由于不同数据类型在不同平台上占用的字节数可能不同,使用
sizeof
能保证代码在不同平台上都可以正确运行。 - 数据结构分析:通过
sizeof
可以分析结构体或者类的内存布局情况。
③语法格式
sizeof
有两种使用语法:
- 针对数据类型:
sizeof(type_name)
- 针对表达式:
sizeof(expression)
或者sizeof expression
下面是一些具体的例子:
sizeof(int); // 返回int类型占用的字节数
sizeof(double); // 返回double类型占用的字节数
sizeof(arr); // 返回数组占用的总字节数
sizeof obj; // 返回对象占用的字节数(可以省略括号)
#include <iostream>
using namespace std;
int main() {cout << "short 类型所占内存空间为: " << sizeof(short) << endl;
//short 类型所占内存空间为: 2cout << "int 类型所占内存空间为: " << sizeof(int) << endl;
//int 类型所占内存空间为: 4cout << "long 类型所占内存空间为: " << sizeof(long) << endl;
//long 类型所占内存空间为: 4cout << "long long 类型所占内存空间为: " << sizeof(long long) << endl;
//long long 类型所占内存空间为: 8system("pause");return 0;
}
④基本数据类型的sizeof
结果
在 32 位系统和 64 位系统中,基本数据类型的sizeof
结果通常如下(但最终还是要以编译器的实现为准):
sizeof(char) // 1字节
sizeof(short) // 2字节
sizeof(int) // 4字节
sizeof(long) // 4字节(32位系统)或8字节(64位系统)
sizeof(long long) // 8字节
sizeof(float) // 4字节
sizeof(double) // 8字节
sizeof(bool) // 1字节
⑤数组与指针的sizeof
数组:sizeof
返回的是整个数组占用的内存字节数。
int arr[10];
sizeof(arr); // 返回40(假设int占4字节)
sizeof(arr) / sizeof(arr[0]); // 计算数组元素个数,结果为10
指针:sizeof
返回的是指针变量本身占用的内存大小,一般在 32 位系统下是 4 字节,在 64 位系统下是 8 字节。
int* ptr = new int[10];
sizeof(ptr); // 返回4或8(取决于系统)
⑥结构体与类的sizeof
结构体和类的sizeof
结果可能会受到内存对齐的影响。
struct MyStruct {char c; // 1字节int i; // 4字节(通常需要对齐到4字节边界)double d; // 8字节
};sizeof(MyStruct); // 通常是16字节(受内存对齐影响)
⑦函数参数中的数组
当数组作为函数参数时,会退化为指针,此时sizeof
返回的是指针的大小。
void func(int arr[]) {sizeof(arr); // 返回4或8(指针大小),而非数组大小
}
⑧例题
例题 1:计算数组元素个数
#include <iostream>
using namespace std;int main() {int arr[] = {1, 2, 3, 4, 5};int size = sizeof(arr) / sizeof(arr[0]);cout << "数组元素个数: " << size << endl; // 输出5return 0;
}
例题 2:结构体的内存布局
#include <iostream>
using namespace std;struct Data {char a; // 1字节int b; // 4字节(对齐到4字节边界)short c; // 2字节
};int main() {cout << "Data大小: " << sizeof(Data) << endl; // 输出12(受对齐影响)return 0;
}
例题 3:动态内存分配
#include <iostream>
using namespace std;int main() {int n = 10;int* arr = new int[n];cout << "指针大小: " << sizeof(arr) << endl; // 输出4或8delete[] arr;return 0;
}
3.实型
①实型的含义与作用
实型用于存储实数(即带有小数点的数值),广泛应用于科学计算、工程模拟、金融计算等需要高精度数值的场景。与整数类型不同,实型可以表示小数部分和极大 / 极小的数值。
②实型的分类与语法格式
C++ 提供了三种基本实型,精度和存储范围逐级递增:
语法格式
float 变量名 = 值;
double 变量名 = 值;
long double 变量名 = 值;
③实型的字面值与精度控制
-
字面值后缀:
f
或F
:指定为float
类型(如3.14f
)。l
或L
:指定为long double
类型(如3.1415926535L
)。- 无后缀:默认为
double
类型(如3.14
)。
-
精度控制:
使用iomanip
头文件中的setprecision()
控制输出精度:
#include <iostream>
#include <iomanip> // 用于精度控制
using namespace std;int main() {double pi = 3.1415926535;cout << fixed << setprecision(4) << pi; // 输出3.1416(四舍五入)return 0;
}
④实型的运算与注意事项
-
运算特性:
实型支持基本算术运算(+、-、*、/),但需注意浮点误差。例如:
float a = 0.1f;
float b = 0.2f;
if ((a + b) == 0.3f) { // 可能不成立!cout << "相等";
} else {cout << "不相等,因为0.1+0.2≈0.300000012";
}
⑤例题与代码示例
例 1:计算圆的面积
#include <iostream>
using namespace std;int main() {double radius = 5.0;double area = 3.14159 * radius * radius; // 使用double类型保证精度cout << "圆的面积是:" << area << endl;return 0;
}
例 2:温度转换(华氏→摄氏)
#include <iostream>
using namespace std;int main() {float fahrenheit;cout << "请输入华氏温度:";cin >> fahrenheit;float celsius = (fahrenheit - 32) * 5.0f / 9.0f; // 使用float类型cout << "摄氏温度是:" << celsius << "°C" << endl;return 0;
}
例 3:高精度计算
#include <iostream>
#include <iomanip>
using namespace std;int main() {long double distance = 9.4607e15; // 一光年(米)long double time = 365.25 * 24 * 60 * 60; // 一年的秒数long double speed = distance / time; // 光速(米/秒)cout << fixed << setprecision(2) << "光速:" << speed << " m/s" << endl;return 0;
}
⑥实型的优缺点
-
优点:
- 可以表示小数和极大 / 极小的数值。
- 支持科学计数法(如
3.14e2
表示 314)。
-
缺点:
- 存在精度限制,可能导致舍入误差。
- 运算速度比整数慢。
4.字符型
①基本字符型:char
②含义
char
是 C++ 中最基本的字符类型,通常占用 1 字节(8 位) 内存空间,范围为 -128 到 127 或 0 到 255(取决于编译器是否将其视为有符号类型)。
③作用
- 存储单个字符(如字母、数字、标点符号)。
- 处理文本数据,如字符串(C 风格字符串以
\0
结尾的char
数组)。 - 作为小型整数使用(范围有限)。
④语法格式
char ch = 'A'; // 单引号用于字符字面量
char newline = '\n'; // 转义字符
char num = '5'; // 字符 '5',而非数字 5
⑤字符与整数的关系
字符在内存中以整数形式存储,可以与整数相互转换:
char ch = 'A'; // ASCII 值为 65
int num = ch; // num = 65
char c = 66; // c = 'B'(ASCII 66)// 输出字符及其 ASCII 值
std::cout << ch << " 的 ASCII 值是: " << static_cast<int>(ch) << std::endl;
⑥扩展字符类型
C++ 提供了几种扩展字符类型,用于处理更大范围的字符集:
wchar_t
:宽字符类型,用于表示 Unicode 字符,通常为 2 或 4 字节。
wchar_t wc = L'中'; // 宽字符字面量需加前缀 L
char16_t
和 char32_t
:C++11 引入,分别用于 UTF-16 和 UTF-32 编码的 Unicode 字符。
char16_t u16 = u'好'; // UTF-16
char32_t u32 = U'😀'; // UTF-32
⑦字符输入输出
输入:使用 cin
或 getchar()
。
char ch;
std::cin >> ch; // 输入单个字符(忽略空白字符)
ch = std::getchar(); // 输入单个字符(包括空白字符)
输出:使用 cout
或 putchar()
。
std::cout << ch; // 输出字符
std::putchar(ch); // 输出字符
⑧例题与应用
例题 1:统计字符串中的字母数
#include <iostream>
#include <cctype> // 字符处理函数库
int main() {char str[] = "Hello, World!";int count = 0;for (int i = 0; str[i] != '\0'; i++) {if (std::isalpha(str[i])) { // 判断是否为字母count++;}}std::cout << "字母数量: " << count << std::endl; // 输出: 10return 0;
}
例题 2:大小写转换
char ch = 'a';
char upper = std::toupper(ch); // 'A'
char lower = std::tolower('B'); // 'b'
例题 3:判断字符类型
char ch = '5';
bool isDigit = std::isdigit(ch); // true
bool isSpace = std::isspace('\t'); // true
⑨注意事项
-
单引号与双引号:
- 单引号
'
用于字符字面量(如'A'
)。 - 双引号
"
用于字符串字面量(如"A"
是包含'A'
和'\0'
的字符数组)。
- 单引号
-
有符号与无符号:
char
是否有符号由编译器决定,可显式指定signed char
或unsigned char
。 -
字符串处理:
C++ 标准库提供std::string
类,比 C 风格字符串更安全易用。
5.转义字符
①含义
转义字符是由反斜杠\
和特定字符组合而成的字符序列,它的主要作用是在代码里表示一些特殊字符,像换行符、制表符等。
②作用
转义字符主要有以下几个方面的作用:
- 表达特殊字符:对于那些无法直接输入的字符,比如换行符、制表符等,就可以用转义字符来表示。
- 避免语法冲突:当需要在字符串中使用引号或者反斜杠本身时,转义字符能帮助我们避免与语法产生冲突。
- 提升可读性:在代码中合理使用转义字符,能够让一些特殊字符的表达更加清晰易懂。
③语法格式
转义字符的语法格式是\
后面跟上特定字符,下面是一些常见的转义字符及其含义:
④例题
例 1:换行符的使用
#include <iostream>
using namespace std;int main() {cout << "Hello\nWorld!" << endl;return 0;
}
例 2:制表符的使用
#include <iostream>
using namespace std;int main() {cout << "Name\tAge\tCity" << endl;cout << "John\t25\tNew York" << endl;cout << "Alice\t30\tLos Angeles" << endl;return 0;
}
6.字符串类型
①C 风格
(1)含义
C 风格字符串是由字符数组组成,以空字符'\0'
结尾,用于表示文本数据。
(2)作用
- 与 C 语言兼容,可用于传统 C 函数(如
printf
、strcpy
等)。 - 在性能敏感场景中使用(如嵌入式系统)。
(3)语法格式
// 方式1:字符数组初始化
char str1[] = "Hello"; // 自动添加'\0',长度为6
char str2[10] = "World"; // 指定数组大小,剩余位置补'\0'// 方式2:字符指针
const char* str3 = "C++"; // 指向字符串常量,不可修改内容
(4)注意事项
- 数组大小需足够容纳字符串和结尾的
'\0'
。 - 修改字符串常量(如
str3[0] = 'D';
)会导致未定义行为。
②C++ 标准库的string
类
(1)含义
string
是 C++ 标准库提供的类,封装了字符串操作,自动管理内存,使用更安全便捷。
(2)作用
- 替代 C 风格字符串,提供更高级的字符串操作(如拼接、查找、替换等)。
- 自动处理内存分配,避免缓冲区溢出。
(3)语法格式
#include <string> // 需包含头文件// 初始化
std::string s1 = "Hello"; // 直接赋值
std::string s2("World"); // 构造函数初始化
std::string s3 = s1 + " " + s2; // 字符串拼接
(4)常用成员函数
s.length(); // 返回字符串长度
s.empty(); // 判断是否为空
s.substr(1, 3); // 截取子串(从索引1开始,长度3)
s.find("ll"); // 查找子串,返回首次出现的索引
s.replace(0, 2, "Hi"); // 替换部分内容
s += "!"; // 追加字符串
(5)例题与应用场景
例题 1:C 风格字符串操作
题目:编写函数计算字符串长度(不使用strlen
)。
#include <iostream>
int customStrlen(const char* str) {int len = 0;while (str[len] != '\0') {len++;}return len;
}int main() {char str[] = "Example";std::cout << "Length: " << customStrlen(str) << std::endl; // 输出:7return 0;
}
例题 2:string
类的应用
题目:反转字符串并统计元音字母数量。
#include <iostream>
#include <string>
#include <algorithm> // 用于std::reverseint countVowels(const std::string& str) {int count = 0;for (char c : str) {c = std::tolower(c);if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {count++;}}return count;
}int main() {std::string s = "Hello World";std::reverse(s.begin(), s.end()); // 反转字符串std::cout << "Reversed: " << s << std::endl; // 输出:dlroW olleHstd::cout << "Vowels: " << countVowels(s) << std::endl; // 输出:3return 0;
}
③C 风格字符串与string
类的对比
7.布尔类型
①含义与作用
- 含义:布尔类型主要用于表达逻辑上的真与假,是逻辑运算的基础数据类型。
- 作用:在条件判断、循环控制以及逻辑运算中,布尔类型发挥着关键作用,能够帮助程序依据不同条件来执行相应操作。
②语法格式
- 声明变量:采用
bool 变量名;
的形式来声明布尔变量。 - 赋值操作:可以将布尔字面量
true
或者false
赋值给布尔变量,也能通过布尔表达式的计算结果来赋值。
③布尔字面量
true
:代表逻辑真。false
:代表逻辑假。
④布尔表达式
借助关系运算符(如==
、>
、<
等)和逻辑运算符(如&&
、||
、!
),可以构建出布尔表达式,其计算结果为布尔值。
- 关系运算符示例:
5 > 3
的结果是true
,5 == 3
的结果是false
。 - 逻辑运算符示例:
(5 > 3) && (4 < 2)
的结果是false
。
⑤隐式类型转换
- 数值转布尔:在进行布尔运算时,非零值会被转换为
true
,而零值会被转换为false
。 - 布尔转数值:在需要数值的上下文中,
true
会被转换为整数1
,false
会被转换为整数0
。
⑥示例代码
下面通过几个例子,展示布尔类型在实际编程中的常见用法:
#include <iostream>
using namespace std;int main() {// 声明并初始化布尔变量bool isStudent = true;bool hasLicense = false;// 关系表达式返回布尔值bool isGreater = (10 > 5); // truebool isEqual = (10 == 5); // false// 逻辑表达式bool isValid = (isStudent && hasLicense); // falsebool isInvalid = !(isStudent || hasLicense); // false// 条件语句中的布尔值if (isStudent) {cout << "该用户是学生" << endl;}// 布尔值与整数的隐式转换int result = true + 5; // true 转换为 1,结果为 6cout << "true + 5 = " << result << endl;// 布尔值作为函数返回值bool isEven(int num) {return (num % 2 == 0);}cout << "4 是偶数: " << (isEven(4) ? "true" : "false") << endl;return 0;
}
输出结果
该用户是学生
true + 5 = 6
4 是偶数: true
⑦注意事项
- 不要把布尔值
true
和整数1
、布尔值false
和整数0
完全等同起来。尽管它们之间可以进行隐式转换,但在语义上是有差别的。 - 在条件判断中,要避免写出类似
if (isStudent == true)
这样冗余的代码,直接使用if (isStudent)
就可以了。
8.数据的输入与输出
①标准输入输出流
C++ 的标准输入输出流主要依赖于以下对象:
- cin:标准输入流对象,用于从键盘读取数据。
- cout:标准输出流对象,用于向屏幕输出数据。
- cerr:标准错误流对象,用于输出错误信息。
- clog:标准日志流对象,用于输出日志信息。
②输出操作(使用 cout)
含义:将数据从程序传输到标准输出设备(通常是屏幕)。
作用:显示程序运行结果、提示信息等。
语法格式:
cout << 表达式1 << 表达式2 << ... << 表达式n;
其中<<
是流插入运算符,用于将右侧的表达式值插入到输出流中。
例题 1:输出变量和文本
#include <iostream>
using namespace std;int main() {int age = 25;string name = "Alice";cout << "My name is " << name << ", and I am " << age << " years old." << endl;return 0;
}
输出结果:
My name is Alice, and I am 25 years old.
③输入操作(使用 cin)
含义:从标准输入设备(通常是键盘)读取数据到程序中。
作用:获取用户输入,使程序具有交互性。
语法格式:
cin >> 变量1 >> 变量2 >> ... >> 变量n;
例题 2:读取用户输入并计算
#include <iostream>
using namespace std;int main() {int a, b;cout << "Enter two integers: ";cin >> a >> b;int sum = a + b;cout << "The sum is: " << sum << endl;return 0;
}
运行示例:
Enter two integers: 10 25
The sum is: 35
④格式化输入输出
C++ 提供了多种方式来格式化输入输出:
- 使用流操纵符:如
setw
(设置字段宽度)、setprecision
(设置浮点数精度)等,需包含<iomanip>
头文件。 - 使用成员函数:如
width()
、precision()
等。
例题 3:格式化输出示例
#include <iostream>
#include <iomanip>
using namespace std;int main() {double pi = 3.1415926535;cout << fixed << setprecision(4); // 设置固定小数位输出,精度为4cout << "Pi is approximately: " << pi << endl;int number = 42;cout << "Number in hexadecimal: " << hex << number << endl;cout << setw(10) << "Left" << setw(10) << "Right" << endl; // 设置字段宽度return 0;
}
输出结果:
Pi is approximately: 3.1416
Number in hexadecimal: 2a
Left Right
④文件输入输出
除了标准输入输出,C++ 还支持文件的读写操作,主要通过以下类实现:
- ifstream:用于从文件读取数据(输入文件流)。
- ofstream:用于向文件写入数据(输出文件流)。
- fstream:用于读写文件(文件流)。
例题 4:文件读写示例
#include <iostream>
#include <fstream>
using namespace std;int main() {// 写入文件ofstream outFile("data.txt");if (outFile.is_open()) {outFile << "Hello, File I/O!" << endl;outFile << 12345 << endl;outFile.close();} else {cerr << "Unable to open file for writing!" << endl;return 1;}// 读取文件ifstream inFile("data.txt");string line;int number;if (inFile.is_open()) {getline(inFile, line); // 读取一行文本inFile >> number; // 读取一个整数cout << "Read from file: " << line << endl;cout << "Number: " << number << endl;inFile.close();} else {cerr << "Unable to open file for reading!" << endl;return 1;}return 0;
}
输出结果:
Read from file: Hello, File I/O!
Number: 12345
⑤注意事项
- 类型匹配:输入时要确保变量类型与输入数据类型匹配,否则可能导致输入失败。
- 输入缓冲区:
cin
读取数据后,换行符可能留在缓冲区,影响后续输入。可使用cin.ignore()
清除缓冲区。 - 文件操作:打开文件后要检查是否成功打开,并在使用完毕后关闭文件。
- 错误处理:可通过
cin.fail()
检查输入是否失败,通过ifstream/ofstream
的状态检查文件操作是否成功。