02.数据类型

目录介绍
  • 3.1 基本数据
    • 3.1.1 基本数据类型
  • 3.2 整数类型
    • 3.2.1 有符号类型
    • 3.2.2 无符号类型
    • 3.2.3 固定宽度整数类型
  • 3.3 字符类型
    • 3.3.1 字符类型列表
    • 3.3.2 字符类型特点
    • 3.3.3 使用场景
    • 3.3.4 注意事项
  • 3.4 浮点类型
    • 3.4.1 浮点类型列表
    • 3.4.2 浮点类型特点
    • 3.4.3 使用场景
    • 3.4.4 注意事项
    • 3.4.5 浮点数特殊值
  • 3.5 布尔类型
  • 3.6 变量和常量
    • 3.6.1 变量
    • 3.6.2 常量
  • 3.7 类型转换
    • 3.7.1 隐式类型转换
    • 3.7.2 显式类型转换
      • 3.7.2.1 static_cast
      • 3.7.2.2 dynamic_cast
      • 3.7.2.3 const_cast
      • 3.7.3.4 reinterpret_cast
    • 3.7.3 类型转换建议
    • 3.7.4 类型转换总结
  • 3.8 练习题
    • 3.5.1 类型转换案例
    • 3.5.2 键盘数据输入

3.1 基本数据

3.1.1 基本数据类型

基本数据类型:

  1. int:整数类型,用于表示整数值。
  2. float:单精度浮点数类型,用于表示小数值。
  3. double:双精度浮点数类型,用于表示更大范围和更高精度的小数值。
  4. char:字符类型,用于表示单个字符。
  5. bool:布尔类型,用于表示真或假的值。

3.2 整数类型

作用:整型变量表示的是==整数类型==的数据

这些整型数据类型可以使用带符号(可以表示正数和负数)或无符号(仅表示非负数)修饰符进行声明。

3.2.1 有符号类型

有符号类型可以存储负数、正数和零,其中最高位用于表示符号(0 表示正数,1 表示负数)。

在 C++ 中,默认情况下,整数类型是有符号的,除非显式地使用 unsigned 关键字声明为无符号类型。

C++中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同

数据类型占用空间取值范围
short(短整型)2字节(-2^15 ~ 2^15-1)
int(整型)4字节(-2^31 ~ 2^31-1)
long(长整形)Windows为4字节,Linux为4字节(32位),8字节(64位)(-2^31 ~ 2^31-1)
long long(长长整形)8字节(-2^63 ~ 2^63-1)

3.2.2 无符号类型

无符号类型是指只能表示非负数(包括零)的数据类型。例如,unsigned int表示无符号整数。

此外,C++还提供了其他整型数据类型,如signed、unsigned short、unsigned long等,它们提供了不同的位数和范围,以满足不同的需求。

数据类型占用空间(字节)取值范围(最小值到最大值)
unsigned char10 到 255
unsigned short20 到 65,535
unsigned int40 到 4,294,967,295
unsigned long4 或 80 到 4,294,967,295(4 字节)
0 到 18,446,744,073,709,551,615(8 字节)
unsigned long long80 到 18,446,744,073,709,551,615

无符号整数类型的特点

  1. 只能表示非负数:无符号整数类型不能表示负数,最小值为 0。
  2. 更大的正数范围:由于不需要存储符号位,无符号整数类型可以表示比有符号类型更大的正数。
  3. 溢出行为:如果超出取值范围,会发生溢出,结果会从 0 重新开始(模运算)。

3.2.3 固定宽度整数类型

C++11 引入了 固定宽度的整数类型,这些类型定义在 <cstdint> 头文件中。它们提供了明确大小的整数类型,方便跨平台开发时确保数据大小的一致性。

数据类型占用空间(字节)取值范围(有符号)取值范围(无符号)
int8_t1-128 到 127-
uint8_t1-0 到 255
int16_t2-32,768 到 32,767-
uint16_t2-0 到 65,535
int32_t4-2,147,483,648 到 2,147,483,647-
uint32_t4-0 到 4,294,967,295
int64_t8-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807-
uint64_t8-0 到 18,446,744,073,709,551,615

固定宽度整数类型的特点

  1. 明确的大小: 固定宽度整数类型的大小是明确的,例如 int32_t 始终是 4 字节。
  2. 跨平台一致性: 使用固定宽度整数类型可以确保代码在不同平台上具有相同的行为。
  3. 可选性: 如果平台不支持某种固定宽度类型(例如 int8_t),则编译器可能不会定义该类型。

示例代码

#include <iostream>
#include <cstdint> // 包含固定宽度整数类型
using namespace std;

int main() {
    // 固定宽度有符号整数类型
    int8_t i8 = -128;
    int16_t i16 = -32768;
    int32_t i32 = -2147483648;
    int64_t i64 = -9223372036854775807LL;

    // 固定宽度无符号整数类型
    uint8_t u8 = 255;
    uint16_t u16 = 65535;
    uint32_t u32 = 4294967295;
    uint64_t u64 = 18446744073709551615ULL;

    // 输出
    cout << "int8_t: " << sizeof(i8) << " bytes, value: " << (int)i8 << endl;
    cout << "int16_t: " << sizeof(i16) << " bytes, value: " << i16 << endl;
    cout << "int32_t: " << sizeof(i32) << " bytes, value: " << i32 << endl;
    cout << "int64_t: " << sizeof(i64) << " bytes, value: " << i64 << endl;

    cout << "uint8_t: " << sizeof(u8) << " bytes, value: " << (int)u8 << endl;
    cout << "uint16_t: " << sizeof(u16) << " bytes, value: " << u16 << endl;
    cout << "uint32_t: " << sizeof(u32) << " bytes, value: " << u32 << endl;
    cout << "uint64_t: " << sizeof(u64) << " bytes, value: " << u64 << endl;

    return 0;
}

输出示例

int8_t: 1 bytes, value: -128
int16_t: 2 bytes, value: -32768
int32_t: 4 bytes, value: -2147483648
int64_t: 8 bytes, value: -9223372036854775807
uint8_t: 1 bytes, value: 255
uint16_t: 2 bytes, value: 65535
uint32_t: 4 bytes, value: 4294967295
uint64_t: 8 bytes, value: 18446744073709551615

使用场景

  1. 跨平台开发:确保整数类型在不同平台上具有相同的大小和行为。
  2. 网络编程:处理网络协议时,通常需要明确的数据大小。
  3. 文件格式:读写二进制文件时,使用固定宽度类型可以确保数据的一致性。
  4. 硬件编程:与硬件寄存器交互时,通常需要明确的数据大小。

3.3 字符类型

C++ 中的字符类型用于存储单个字符或小整数值。字符类型在 C++ 中非常重要,因为它们不仅用于表示字符,还可以用于处理 ASCII 值或进行位操作。

3.3.1 字符类型列表

作用:字符型变量用于显示单个字符

数据类型占用空间(字节)描述
char1默认字符类型,通常用于存储 ASCII 字符。可以是有符号或无符号,取决于平台。
signed char1明确表示有符号的字符类型,取值范围:-128 到 127。
unsigned char1明确表示无符号的字符类型,取值范围:0 到 255。
wchar_t2 或 4宽字符类型,用于存储 Unicode 字符。大小取决于平台(Windows 通常为 2 字节,Linux 通常为 4 字节)。
char16_t2用于存储 UTF-16 编码的字符(C++11 引入)。
char32_t4用于存储 UTF-32 编码的字符(C++11 引入)。

语法:char ch = 'a';

  • C和C++中字符型变量只占用==1个字节==。
  • 字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元。

示例:

#include <iostream>
using namespace std;
int main() {
    char ch = 'a';
    cout << ch << endl;
    cout << sizeof(char) << endl;
    //ch = "abcde"; //错误,不可以用双引号
    //ch = 'abcde'; //错误,单引号内只能引用一个字符
    cout << (int) ch << endl;  //查看字符a对应的ASCII码
    ch = 97; //可以直接用ASCII给字符型变量赋值
    cout << ch << endl;
    return 0;
}
//a
//1
//97
//a

3.3.2 字符类型特点

  1. char 类型:默认情况下,char 可以是有符号或无符号,具体取决于编译器和平台。 通常用于存储 ASCII 字符(0 到 127)。
  2. signed charunsigned char: 明确表示有符号或无符号的字符类型。常用于处理小整数值或进行位操作。
  3. 宽字符类型wchar_tchar16_tchar32_t 用于存储 Unicode 字符。wchar_t 的大小取决于平台,而 char16_tchar32_t 的大小是固定的。
  4. 字符字面量:单引号用于表示字符字面量,例如 'A'。宽字符字面量使用前缀 Lwchar_t)、uchar16_t)或 Uchar32_t),例如 L'中'u'中'U'中'

3.3.3 使用场景

  1. 文本处理char 类型用于处理 ASCII 字符或字符串。宽字符类型用于处理 Unicode 字符。
  2. 位操作unsigned char 常用于位操作,因为它可以表示 0 到 255 的值。
  3. 小整数存储signed charunsigned char 可以用于存储小整数值。
  4. 国际化支持wchar_tchar16_tchar32_t 用于支持多语言字符集。

3.3.4 注意事项

  1. char 的符号性char 的符号性取决于平台,如果需要明确的有符号或无符号行为,请使用 signed charunsigned char
  2. 宽字符类型的大小wchar_t 的大小因平台而异,而 char16_tchar32_t 的大小是固定的。
  3. 字符字面量的前缀:使用宽字符字面量时,确保使用正确的前缀(LuU)。
  4. 字符与整数的转换:字符类型可以隐式转换为整数类型,但需要注意取值范围。

3.4 浮点类型

C++ 中的浮点类型用于表示实数(即带小数点的数字)。它们基于 IEEE 754 标准,提供了不同精度的浮点数表示。

作用:用于==表示小数==

浮点型变量分为两种:

  1. 单精度float
  2. 双精度double

两者的区别在于表示的有效数字范围不同。

3.4.1 浮点类型列表

数据类型占用空间(字节)精度(有效数字)取值范围(近似)
float46-9 位±1.18e-38 到 ±3.4e38
double815-17 位±2.23e-308 到 ±1.8e308
long double8、12 或 1618-21 位取决于平台,通常与 double 相同或更高

3.4.2 浮点类型特点

  1. 精度
  • float 提供单精度浮点数,适合对精度要求不高的场景。
  • double 提供双精度浮点数,适合大多数科学计算和工程应用。
  • long double 提供扩展精度,适合对精度要求极高的场景。
  1. 取值范围: 浮点类型的取值范围非常大,可以表示非常小或非常大的数。
  2. 存储格式: 浮点数采用 IEEE 754 标准存储,分为符号位、指数位和尾数位。
  3. 字面量
  • 浮点数字面量默认是 double 类型。
  • 使用后缀 fF 表示 float 类型,例如 3.14f
  • 使用后缀 lL 表示 long double 类型,例如 3.14L

3.4.3 使用场景

  1. 科学计算double 是科学计算中最常用的浮点类型,提供了足够的精度和范围。
  2. 图形处理float 常用于图形处理,因为其精度足够且占用内存较少。
  3. 金融计算: 对于高精度计算(如货币计算),可以使用 long double 或专门的库(如 decimal)。
  4. 物理模拟: 物理模拟中通常使用 doublelong double 以确保精度。

3.4.4 注意事项

  1. 精度损失: 浮点数在计算时可能会产生精度损失,尤其是在进行大量运算时。
  2. 比较浮点数: 由于浮点数的精度问题,直接比较两个浮点数是否相等可能会导致错误。通常使用一个很小的误差范围(如 1e-9)进行比较。
  3. 溢出和下溢: 浮点数可能会溢出(超过最大值)或下溢(接近零),导致结果不准确。
  4. 平台差异long double 的大小和精度可能因平台而异。

3.4.5 浮点数特殊值

浮点数可以表示一些特殊值:

  • 无穷大INFINITY(正无穷)和 -INFINITY(负无穷)。
  • 非数字NaN(Not a Number),表示无效的浮点数操作结果。
#include <iostream>
#include <cmath> // 包含 INFINITY 和 NaN
using namespace std;
int main() {
    double inf = INFINITY;
    double nan = NAN;
    cout << "Infinity: " << inf << endl;
    cout << "NaN: " << nan << endl;
    return 0;
}

输出:

Infinity: inf
NaN: nan

3.5 布尔类型

作用:布尔数据类型代表真或假的值

类型大小(字节)
bool1truefalse
  • true --- 真(本质是1)
  • false --- 假(本质是0)

示例:

#include <iostream>
using namespace std;
int main() {
    bool flag = true;
    cout << flag << endl; // 1
    flag = false;
    cout << flag << endl; // 0
    cout << "size of bool = " << sizeof(bool) << endl; //1
    return 0;
}
//1
//0
//size of bool = 1

3.6 变量和常量

3.6.1 变量

作用:给一段指定的内存空间起名,方便操作这段内存。

语法数据类型 变量名 = 初始值;

示例

#include <iostream>
using namespace std;

int main() {
    //变量的定义
    //语法:数据类型  变量名 = 初始值
    int a = 10;
    cout << "a = " << a << endl;
    return 0;
}

3.6.2 常量

作用:用于记录程序中不可更改的数据

C++定义常量两种方式

  1. #define 宏常量: #define 常量名 常量值

==通常在文件上方定义==,表示一个常量

  1. const修饰的变量 const 数据类型 常量名 = 常量值

==通常在变量定义前加关键字const==,修饰该变量为常量,不可修改

示例:

#include <iostream>
using namespace std;

//1.宏常量
#define day = 7;

int main() {
    //cout << "一周里总共有 %d" << day << " 天" << endl;
    //printf("一周里总共有:%dn",day);
    //day = 8;  //报错,宏常量不可以修改
    //2、const修饰变量
    const int month = 12;
    cout << "一年里总共有 " << month << " 个月份" << endl;
    //month = 24; //报错,常量是不可以修改的
    return 0;
}

3.7 类型转换

在 C++ 中,类型转换 是将一种数据类型转换为另一种数据类型的过程。C++ 提供了多种类型转换方式,包括隐式转换和显式转换。

显式转换又分为 C 风格转换和 C++ 风格转换(static_castdynamic_castconst_castreinterpret_cast)。

3.7.1 隐式类型转换

隐式类型转换由编译器自动完成,通常发生在赋值、表达式计算或函数调用时。

示例

int a = 10;
double b = a; // 隐式将 int 转换为 double

int c = 3.14; // 隐式将 double 转换为 int(丢失小数部分)

3.7.2 显式类型转换

1.C风格转换,C 风格转换使用 (目标类型) 的语法。

double d = 3.14;
int e = (int)d; // 显式将 double 转换为 int

2.C++风格转换,C++ 提供了四种显式转换运算符,更加安全和明确。

3.7.2.1 static_cast

用于基本数据类型之间的转换,以及具有继承关系的类之间的转换。

double f = 3.14;
int g = static_cast<int>(f); // 显式将 double 转换为 int

class Base {};
class Derived : public Base {};
Base* basePtr = new Derived;
Derived* derivedPtr = static_cast<Derived*>(basePtr); // 向下转型
3.7.2.2 dynamic_cast

用于具有多态性的类之间的转换(通常用于向下转型),转换失败时返回 nullptr

class Base { virtual void foo() {} };
class Derived : public Base {};

Base* basePtr = new Derived;
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 向下转型
if (derivedPtr) {
    cout << "转换成功" << endl;
} else {
    cout << "转换失败" << endl;
}
3.7.2.3 const_cast

用于移除或添加 constvolatile 修饰符。

const int h = 10;
int* i = const_cast<int*>(&h); // 移除 const 修饰符
*i = 20; // 修改值(未定义行为,不推荐)
3.7.3.4 reinterpret_cast

用于低级别的类型转换,通常用于指针或整数之间的转换。

int j = 42;
int* ptr = &j;
long k = reinterpret_cast<long>(ptr); // 将指针转换为整数

3.7.3 类型转换建议

  1. 优先使用 C++ 风格转换: C++ 风格转换更加安全和明确,避免使用 C 风格转换。
  2. 避免不必要的转换: 类型转换可能导致数据丢失或未定义行为,尽量避免。
  3. 谨慎使用 const_cast: 移除 const 修饰符可能导致未定义行为,应谨慎使用。
  4. 使用 dynamic_cast 进行安全的向下转型:在具有多态性的类之间转换时,优先使用 dynamic_cast

3.7.4 类型转换总结

  • 隐式转换由编译器自动完成,显式转换需要程序员明确指定。
  • C++ 提供了四种显式转换运算符:static_castdynamic_castconst_castreinterpret_cast
  • 优先使用 C++ 风格转换,避免不必要的转换,谨慎使用 const_cast

3.8 练习题

3.8.1 类型转换案例

#include <iostream>
using namespace std;

class Base {
public:
    virtual void foo() { cout << "Base::foo" << endl; }
};

class Derived : public Base {
public:
    void foo() override { cout << "Derived::foo" << endl; }
};

int main() {
    // 隐式转换
    int a = 10;
    double b = a;
    cout << "b = " << b << endl;

    // C 风格转换
    double c = 3.14;
    int d = (int)c;
    cout << "d = " << d << endl;

    // C++ 风格转换
    double e = 3.14;
    int f = static_cast<int>(e);
    cout << "f = " << f << endl;

    // dynamic_cast
    Base* basePtr = new Derived;
    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
    if (derivedPtr) {
        cout << "dynamic_cast 成功" << endl;
    } else {
        cout << "dynamic_cast 失败" << endl;
    }

    // const_cast
    const int g = 10;
    int* h = const_cast<int*>(&g);
    *h = 20;
    cout << "g = " << g << ", *h = " << *h << endl;

    // reinterpret_cast
    int i = 42;
    int* ptr = &i;
    long j = reinterpret_cast<long>(ptr);
    cout << "j = " << j << endl;

    delete basePtr;
    return 0;
}

3.8.2 键盘数据输入

作用:用于从键盘获取数据

关键字:cin

语法: cin >> 变量

示例:

#include <iostream>
using namespace std;
int main(){
    //整型输入
    int a = 0;
    cout << "请输入整型变量:" << endl;
    cin >> a;
    cout << a << endl;

    //浮点型输入
    double d = 0;
    cout << "请输入浮点型变量:" << endl;
    cin >> d;
    cout << d << endl;

    //字符型输入
    char ch = 0;
    cout << "请输入字符型变量:" << endl;
    cin >> ch;
    cout << ch << endl;

    //字符串型输入
    string str;
    cout << "请输入字符串型变量:" << endl;
    cin >> str;
    cout << str << endl;

    //布尔类型输入
    bool flag = true;
    cout << "请输入布尔型变量:" << endl;
    cin >> flag;
    cout << flag << endl;
    return EXIT_SUCCESS;
}
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]