Appearance
数据类型
C++提供了丰富的数据类型,包括基本数据类型、复合数据类型和用户自定义类型。本章将详细介绍C++的数据类型。
数据类型分类
cpp
#include <iostream>
using namespace std;
/*
* C++数据类型分类:
*
* 1. 基本数据类型(内置类型)
* - 整型:short, int, long, long long
* - 字符型:char, wchar_t, char16_t, char32_t
* - 浮点型:float, double, long double
* - 布尔型:bool
* - 空类型:void
*
* 2. 复合数据类型
* - 数组
* - 指针
* - 引用
* - 函数
*
* 3. 用户自定义类型
* - 结构体(struct)
* - 联合体(union)
* - 枚举(enum)
* - 类(class)
*/
int main() {
// 显示各类型的大小
cout << "===== 基本数据类型大小 =====" << endl;
cout << "bool: " << sizeof(bool) << " 字节" << endl;
cout << "char: " << sizeof(char) << " 字节" << endl;
cout << "short: " << sizeof(short) << " 字节" << endl;
cout << "int: " << sizeof(int) << " 字节" << endl;
cout << "long: " << sizeof(long) << " 字节" << endl;
cout << "long long: " << sizeof(long long) << " 字节" << endl;
cout << "float: " << sizeof(float) << " 字节" << endl;
cout << "double: " << sizeof(double) << " 字节" << endl;
return 0;
}整型
cpp
#include <iostream>
#include <climits> // 包含整型极限值
using namespace std;
int main() {
// ============ 基本整型 ============
// short:短整型(至少16位)
short s = 100;
// int:整型(至少16位,通常32位)
int i = 100000;
// long:长整型(至少32位)
long l = 1000000L; // L后缀表示long
// long long:超长整型(至少64位)
long long ll = 1000000000000LL; // LL后缀表示long long
// ============ 有符号与无符号 ============
// 有符号整型(可以表示负数)
signed int si = -100;
// 无符号整型(只能表示非负数)
unsigned int ui = 100U; // U后缀表示unsigned
// 无符号长整型
unsigned long ul = 100UL; // UL后缀
// 无符号超长整型
unsigned long long ull = 100ULL; // ULL后缀
// ============ 整型极限值 ============
cout << "===== 整型范围 =====" << endl;
// int的范围
cout << "int最小值: " << INT_MIN << endl;
cout << "int最大值: " << INT_MAX << endl;
// unsigned int的范围
cout << "unsigned int最大值: " << UINT_MAX << endl;
// long long的范围
cout << "long long最小值: " << LLONG_MIN << endl;
cout << "long long最大值: " << LLONG_MAX << endl;
// unsigned long long的范围
cout << "unsigned long long最大值: " << ULLONG_MAX << endl;
// ============ 整型溢出 ============
short overflow = 32767; // short最大值
overflow = overflow + 1; // 溢出!变成-32768
cout << "\n溢出示例:" << endl;
cout << "32767 + 1 = " << overflow << endl; // 输出-32768
// 使用无符号类型避免负数溢出
unsigned short safe = 65535;
safe = safe + 1; // 溢出到0
cout << "65535 + 1 = " << safe << endl; // 输出0
// ============ 整数字面量 ============
// 十进制
int decimal = 100;
// 八进制(以0开头)
int octal = 0100; // 等于十进制的64
cout << "\n八进制0100 = " << octal << endl;
// 十六进制(以0x或0X开头)
int hexa = 0x100; // 等于十进制的256
cout << "十六进制0x100 = " << hexa << endl;
// 二进制(C++14,以0b或0B开头)
int binary = 0b100; // 等于十进制的4
cout << "二进制0b100 = " << binary << endl;
// 数字分隔符(C++14,使用单引号)
int million = 1'000'000; // 提高可读性
cout << "一百万 = " << million << endl;
return 0;
}浮点型
cpp
#include <iostream>
#include <cfloat> // 包含浮点型极限值
#include <iomanip>
using namespace std;
int main() {
// ============ 浮点类型 ============
// float:单精度浮点型(通常32位)
float f = 3.14f; // f或F后缀表示float
// double:双精度浮点型(通常64位)
double d = 3.14; // 默认小数是double类型
// long double:扩展精度浮点型
long double ld = 3.14L; // L后缀表示long double
// ============ 浮点型精度 ============
cout << "===== 浮点型精度 =====" << endl;
cout << "float精度位数: " << FLT_DIG << endl; // 通常6位
cout << "double精度位数: " << DBL_DIG << endl; // 通常15位
cout << "long double精度位数: " << LDBL_DIG << endl; // 通常18位
cout << fixed << setprecision(20);
float pi_f = 3.14159265358979323846f;
double pi_d = 3.14159265358979323846;
long double pi_ld = 3.14159265358979323846L;
cout << "\nfloat: " << pi_f << endl;
cout << "double: " << pi_d << endl;
cout << "long double: " << pi_ld << endl;
// ============ 科学计数法 ============
double avogadro = 6.022e23; // 阿伏伽德罗常数
double electron = 1.6e-19; // 电子电荷
cout << scientific;
cout << "\n阿伏伽德罗常数: " << avogadro << endl;
cout << "电子电荷: " << electron << endl;
// ============ 特殊浮点值 ============
// 正无穷
double positiveInf = INFINITY;
cout << "\n正无穷: " << positiveInf << endl;
// 负无穷
double negativeInf = -INFINITY;
cout << "负无穷: " << negativeInf << endl;
// 非数字(NaN)
double nanValue = NAN;
cout << "NaN: " << nanValue << endl;
// 检查特殊值
cout << "\nisinf(INFINITY): " << isinf(positiveInf) << endl;
cout << "isnan(NAN): " << isnan(nanValue) << endl;
cout << "isfinite(3.14): " << isfinite(3.14) << endl;
// ============ 浮点数比较 ============
double a = 0.1 + 0.2;
double b = 0.3;
cout << defaultfloat;
cout << "\n0.1 + 0.2 = " << a << endl;
cout << "0.3 = " << b << endl;
// 直接比较可能失败(浮点精度问题)
if (a == b) {
cout << "a == b" << endl;
} else {
cout << "a != b (浮点精度问题)" << endl;
}
// 正确的比较方法:使用epsilon
double epsilon = 1e-9;
if (abs(a - b) < epsilon) {
cout << "a ≈ b (使用epsilon比较)" << endl;
}
return 0;
}字符型
cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
// ============ char类型 ============
// char:存储单个字符(通常1字节)
char ch1 = 'A'; // 字符字面量
char ch2 = 65; // ASCII码值('A'的ASCII码是65)
char ch3 = '\x41'; // 十六进制转义序列('A')
cout << "ch1 = " << ch1 << endl;
cout << "ch2 = " << ch2 << endl;
cout << "ch3 = " << ch3 << endl;
// ============ signed char 和 unsigned char ============
// signed char:-128 到 127
signed char sc = -10;
// unsigned char:0 到 255
unsigned char uc = 200;
cout << "\nsigned char: " << (int)sc << endl;
cout << "unsigned char: " << (int)uc << endl;
// ============ 宽字符类型 ============
// wchar_t:宽字符类型(存储Unicode字符)
wchar_t wc = L'中'; // L前缀表示宽字符
wcout << L"\n宽字符: " << wc << endl;
// char16_t:UTF-16字符(C++11)
char16_t c16 = u'中'; // u前缀
// char32_t:UTF-32字符(C++11)
char32_t c32 = U'中'; // U前缀
// char8_t:UTF-8字符(C++20)
// char8_t c8 = u8'中'; // u8前缀(C++20)
// ============ 转义字符 ============
cout << "\n===== 转义字符 =====" << endl;
cout << "换行符\\n: " << "Hello\nWorld" << endl;
cout << "制表符\\t: " << "A\tB" << endl;
cout << "回车符\\r: " << "ABC\rXY" << endl; // XY替换ABC的前两个
cout << "反斜杠\\\\: " << "C:\\Path" << endl;
cout << "单引号\\': " << "\'" << endl;
cout << "双引号\\\": " << "\"" << endl;
cout << "空字符\\0: " << "End\0" << endl;
// ============ 字符处理函数 ============
#include <cctype>
char test = 'a';
cout << "\n===== 字符处理函数 =====" << endl;
cout << "isalpha('a'): " << isalpha(test) << endl; // 是否字母
cout << "isdigit('a'): " << isdigit(test) << endl; // 是否数字
cout << "islower('a'): " << islower(test) << endl; // 是否小写
cout << "isupper('a'): " << isupper(test) << endl; // 是否大写
cout << "isspace(' '): " << isspace(' ') << endl; // 是否空白
cout << "toupper('a'): " << (char)toupper(test) << endl; // 转大写
cout << "tolower('A'): " << (char)tolower('A') << endl; // 转小写
return 0;
}布尔型
cpp
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
// ============ bool类型 ============
// bool:布尔类型,只有true和false两个值
bool isTrue = true;
bool isFalse = false;
cout << "isTrue = " << isTrue << endl; // 输出1
cout << "isFalse = " << isFalse << endl; // 输出0
// 使用boolalpha输出true/false
cout << boolalpha;
cout << "isTrue = " << isTrue << endl; // 输出true
cout << "isFalse = " << isFalse << endl; // 输出false
// ============ 布尔值与整数转换 ============
// 整数转布尔:非零为true,零为false
bool b1 = 0; // false
bool b2 = 1; // true
bool b3 = -1; // true(非零)
bool b4 = 0.0; // false
bool b5 = 0.1; // true
cout << noboolalpha;
cout << "\n整数转布尔:" << endl;
cout << "bool(0) = " << b1 << endl;
cout << "bool(1) = " << b2 << endl;
cout << "bool(-1) = " << b3 << endl;
// 布尔转整数:true为1,false为0
int i1 = true; // 1
int i2 = false; // 0
cout << "\n布尔转整数:" << endl;
cout << "int(true) = " << i1 << endl;
cout << "int(false) = " << i2 << endl;
// ============ 布尔运算 ============
bool a = true;
bool b = false;
cout << "\n布尔运算:" << endl;
cout << boolalpha;
cout << "true && false = " << (a && b) << endl; // 逻辑与
cout << "true || false = " << (a || b) << endl; // 逻辑或
cout << "!true = " << !a << endl; // 逻辑非
// ============ 在条件中使用 ============
int score = 75;
bool passed = (score >= 60); // 条件表达式返回bool
cout << "\n分数: " << score << endl;
cout << "及格: " << passed << endl;
if (passed) {
cout << "恭喜,你及格了!" << endl;
} else {
cout << "很遗憾,你需要补考。" << endl;
}
return 0;
}void类型
cpp
#include <iostream>
using namespace std;
// void作为函数返回类型
void printMessage(string msg) {
cout << msg << endl;
// 无返回值
}
// void作为函数参数(表示无参数)
int getValue(void) {
return 42;
}
// void指针可以指向任何类型
void printAnyType(void* ptr, char type) {
switch (type) {
case 'i': // int
cout << "int: " << *(int*)ptr << endl;
break;
case 'd': // double
cout << "double: " << *(double*)ptr << endl;
break;
case 'c': // char
cout << "char: " << *(char*)ptr << endl;
break;
}
}
int main() {
// ============ void作为返回类型 ============
printMessage("Hello, void!");
// ============ void指针 ============
int num = 10;
double pi = 3.14;
char ch = 'A';
// void指针可以指向任何类型
void* ptr;
ptr = #
cout << "\nvoid指针指向int: " << *(int*)ptr << endl;
ptr = π
cout << "void指针指向double: " << *(double*)ptr << endl;
ptr = &ch;
cout << "void指针指向char: " << *(char*)ptr << endl;
// 使用通用打印函数
cout << "\n通用打印函数:" << endl;
printAnyType(&num, 'i');
printAnyType(&pi, 'd');
printAnyType(&ch, 'c');
// 注意:不能定义void类型的变量
// void v; // 错误!
return 0;
}类型转换
隐式类型转换
cpp
#include <iostream>
using namespace std;
int main() {
// ============ 算术转换 ============
// 小类型自动提升为大类型
short s = 10;
int i = s; // short -> int(提升)
long l = i; // int -> long(提升)
// 有符号转无符号(可能出问题)
int negative = -1;
unsigned int positive = negative; // 变成很大的正数
cout << "int(-1) -> unsigned: " << positive << endl;
// 整型转浮点
int intVal = 10;
double doubleVal = intVal; // int -> double
cout << "int(10) -> double: " << doubleVal << endl;
// 浮点转整型(截断小数部分)
double pi = 3.14159;
int intPi = pi; // 截断为3
cout << "double(3.14159) -> int: " << intPi << endl;
// ============ 混合运算转换 ============
int a = 5;
double b = 2.0;
// int和double运算,int提升为double
auto result = a / b; // result是double类型
cout << "\n5 / 2.0 = " << result << endl;
// 整数除法
int intDiv = 5 / 2; // 结果是2(整数除法)
cout << "5 / 2 = " << intDiv << endl;
// ============ 赋值转换 ============
double d = 3.9;
int n = d; // 截断,n = 3
cout << "\ndouble(3.9) -> int: " << n << endl;
// 警告:精度丢失
long long bigNum = 9223372036854775807LL;
int smallNum = bigNum; // 溢出!
cout << "long long -> int: " << smallNum << endl;
return 0;
}显式类型转换
cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
// ============ C风格转换 ============
double pi = 3.14159;
// C风格:(类型)表达式
int intPi1 = (int)pi;
cout << "C风格转换: " << intPi1 << endl;
// 函数风格:类型(表达式)
int intPi2 = int(pi);
cout << "函数风格转换: " << intPi2 << endl;
// ============ C++风格转换(推荐) ============
// static_cast:静态转换(编译时检查)
double d = 3.14;
int i = static_cast<int>(d);
cout << "\nstatic_cast<double->int>: " << i << endl;
// 相关类型之间的转换
char c = 'A';
int ascii = static_cast<int>(c);
cout << "static_cast<char->int>: " << ascii << endl;
// ============ const_cast ============
// 移除const属性(慎用!)
const int constVal = 10;
// constVal = 20; // 错误:不能修改const变量
int* ptr = const_cast<int*>(&constVal);
*ptr = 20; // 危险!可能导致未定义行为
cout << "\nconst_cast后: " << constVal << endl;
// 常用于函数参数传递
void printString(const string& s) {
// 如果需要修改s,可以使用const_cast
// 但通常不应该这样做
}
// ============ reinterpret_cast ============
// 重新解释位模式(危险,慎用)
int num = 65;
int* intPtr = #
// 将int指针转为char指针
char* charPtr = reinterpret_cast<char*>(intPtr);
cout << "\nreinterpret_cast后: " << *charPtr << endl;
// 指针与整数之间的转换
long long ptrValue = reinterpret_cast<long long>(intPtr);
cout << "指针转整数: " << ptrValue << endl;
// ============ dynamic_cast ============
// 用于多态类型的向下转型(需要虚函数)
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {
public:
void derivedMethod() {
cout << "Derived method" << endl;
}
};
Base* basePtr = new Derived();
// 安全的向下转型
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {
cout << "\ndynamic_cast成功" << endl;
derivedPtr->derivedMethod();
}
delete basePtr;
// ============ 转换选择建议 ============
/*
* 选择转换类型的建议:
*
* 1. static_cast:
* - 基本类型之间的转换
* - 有继承关系的类指针/引用转换
* - void*与其他指针之间的转换
*
* 2. const_cast:
* - 移除或添加const属性
* - 移除或添加volatile属性
*
* 3. reinterpret_cast:
* - 指针与整数之间的转换
* - 不相关指针类型之间的转换
* - 函数指针之间的转换
*
* 4. dynamic_cast:
* - 多态类型的向下转型
* - 需要运行时类型检查
*/
return 0;
}auto关键字
cpp
#include <iostream>
#include <vector>
#include <map>
#include <memory>
using namespace std;
// 函数返回类型推导(C++14)
auto add(int a, int b) {
return a + b; // 返回类型推导为int
}
// 返回类型后置(C++11)
auto multiply(int a, int b) -> int {
return a * b;
}
int main() {
// ============ 基本用法 ============
// 自动推导变量类型
auto num = 10; // int
auto pi = 3.14; // double
auto ch = 'A'; // char
auto str = "hello"; // const char*
auto flag = true; // bool
cout << "auto推导的基本类型" << endl;
cout << "num类型大小: " << sizeof(num) << endl;
cout << "pi类型大小: " << sizeof(pi) << endl;
// ============ 推导引用和const ============
int x = 10;
const int cx = 20;
// auto会忽略顶层const和引用
auto a1 = x; // int
auto a2 = cx; // int(忽略了const)
auto& a3 = cx; // const int&(保留const)
// 使用auto&保留const
const auto& a4 = x; // const int&
// auto&& 通用引用
auto&& r1 = x; // int&(左值引用)
auto&& r2 = 10; // int&&(右值引用)
// ============ 简化复杂类型 ============
*
// 传统写法
map<string, vector<int>> data;
map<string, vector<int>>::iterator it1 = data.begin();
// 使用auto简化
auto it2 = data.begin(); // 更简洁
// 智能指针
auto ptr = make_unique<int>(42); // unique_ptr<int>
auto sptr = make_shared<int>(42); // shared_ptr<int>
cout << "\n智能指针值: " << *ptr << endl;
// ============ 范围for循环 ============
vector<int> numbers = {1, 2, 3, 4, 5};
cout << "\n范围for循环:" << endl;
// 使用auto
for (auto n : numbers) {
cout << n << " ";
}
cout << endl;
// 使用auto&修改元素
for (auto& n : numbers) {
n *= 2;
}
// 使用const auto&只读访问
for (const auto& n : numbers) {
cout << n << " ";
}
cout << endl;
// ============ 函数返回类型推导 ============
auto sum = add(10, 20);
auto product = multiply(5, 6);
cout << "\nadd(10, 20) = " << sum << endl;
cout << "multiply(5, 6) = " << product << endl;
// ============ auto使用建议 ============
/*
* auto使用建议:
*
* 优点:
* 1. 简化代码,特别是复杂类型
* 2. 避免类型拼写错误
* 3. 保证变量初始化
* 4. 重构时自动适应类型变化
*
* 注意事项:
* 1. 可读性:确保类型显而易见
* 2. 避免意外的类型转换
* 3. 使用auto&避免不必要的拷贝
* 4. 使用const auto&表示只读
*/
return 0;
}本章小结
本章学习了:
- 整型:short、int、long、long long,有符号与无符号
- 浮点型:float、double、long double,精度与科学计数法
- 字符型:char、wchar_t、char16_t、char32_t,转义字符
- 布尔型:true和false,与整数的转换
- void类型:函数返回值、void指针
- 类型转换:隐式转换、static_cast等C++风格转换
- auto关键字:自动类型推导,简化复杂类型
下一章,我们将学习运算符,了解C++中的各种运算操作。
