Skip to content

C++ 数据类型

在 C++ 中,数据类型决定了变量可以存储什么类型的数据,以及如何存储这些数据。不同的数据类型占用不同大小的内存空间,并且支持不同的操作。在本章节中,我们将介绍 C++ 的各种数据类型。

1. 数据类型的分类

C++ 的数据类型可以分为以下几类:

  1. 基本数据类型:包括整型、浮点型、字符型和布尔型
  2. 派生数据类型:包括数组、指针、引用、函数等
  3. 用户定义类型:包括类、结构体、共用体、枚举等
  4. 空类型:void

2. 基本数据类型

2.1 整型

整型用于存储整数,包括以下几种类型:

类型说明大小(字节)取值范围
char字符型(本质上是小整型)1-128 到 127
signed char有符号字符型1-128 到 127
unsigned char无符号字符型10 到 255
short短整型2-32768 到 32767
unsigned short无符号短整型20 到 65535
int整型4-2147483648 到 2147483647
unsigned int无符号整型40 到 4294967295
long长整型4 或 8取决于系统
unsigned long无符号长整型4 或 8取决于系统
long long长长整型8-9223372036854775808 到 9223372036854775807
unsigned long long无符号长长整型80 到 18446744073709551615

示例:

cpp
char c = 'A';              // 字符型
short s = 1000;            // 短整型
int i = 100000;            // 整型
long l = 1000000L;         // 长整型
long long ll = 10000000000LL;  // 长长整型

unsigned int ui = 4000000000U;  // 无符号整型

2.2 浮点型

浮点型用于存储带有小数点的数值,包括以下几种类型:

类型说明大小(字节)精度
float单精度浮点型4约7位小数
double双精度浮点型8约15位小数
long double长双精度浮点型8 或 16取决于系统

示例:

cpp
float f = 3.14f;           // 单精度浮点型
double d = 3.141592653589793;  // 双精度浮点型
long double ld = 3.14159265358979323846L;  // 长双精度浮点型

2.3 字符型

字符型用于存储单个字符,使用char类型:

cpp
char ch = 'A';  // 存储字符 A
char symbol = '@';  // 存储符号 @

在 C++ 中,字符实际上是存储为 ASCII 码值的,例如:

cpp
char ch = 'A';  // 实际上存储的是 ASCII 码值 65
std::cout << ch << std::endl;  // 输出字符 A
std::cout << (int)ch << std::endl;  // 输出 ASCII 码值 65

2.4 布尔型

布尔型用于存储真值,只有两个值:true(真)和false(假):

cpp
bool flag = true;   // 真
bool is_valid = false;  // 假

布尔型在内存中占用 1 个字节,true 的值为 1,false 的值为 0。

3. 派生数据类型

3.1 数组

数组是相同类型元素的集合,例如:

cpp
int numbers[5];  // 存储 5 个整数的数组
char name[10];  // 存储 10 个字符的数组
double scores[100];  // 存储 100 个双精度浮点数的数组

3.2 指针

指针是存储内存地址的变量,例如:

cpp
int* p;  // 指向整型变量的指针
char* str;  // 指向字符的指针
double* pd;  // 指向双精度浮点数的指针

3.3 引用

引用是变量的别名,例如:

cpp
int a = 10;
int& ref = a;  // ref 是 a 的引用

3.4 函数

函数也是一种派生数据类型,例如:

cpp
int add(int a, int b) {
    return a + b;
}

4. 用户定义类型

4.1 结构体

结构体是不同类型元素的集合,例如:

cpp
struct Person {
    std::string name;
    int age;
    float height;
};

4.2 类

类是 C++ 的核心特性,用于实现面向对象编程,例如:

cpp
class Rectangle {
private:
    double width;
    double height;

public:
    Rectangle(double w, double h) : width(w), height(h) {}
    
    double area() {
        return width * height;
    }
};

4.3 共用体

共用体是一种特殊的数据类型,允许在同一块内存中存储不同类型的数据,例如:

cpp
union Data {
    int i;
    float f;
    char str[20];
};

4.4 枚举

枚举类型是一种特殊的整型,用于定义一组命名的常量,例如:

cpp
enum Weekday {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
};

5. 空类型

空类型void表示没有值或类型,主要用于:

  1. 函数返回类型:表示函数不返回任何值
  2. 函数参数:表示函数不接受任何参数
  3. 指针类型:表示通用指针

例如:

cpp
void print_hello() {
    std::cout << "Hello!" << std::endl;
}

void* ptr;  // 通用指针

6. 类型修饰符

C++ 提供了一些类型修饰符,可以修改基本数据类型的行为:

6.1 signed

表示有符号类型,可以存储正数、负数和零。对于整型,signed是默认的。

cpp
signed int x = -10;  // 可以存储负数

6.2 unsigned

表示无符号类型,只能存储非负数。

cpp
unsigned int y = 10;  // 只能存储非负数

6.3 short

表示短整型,占用较少的内存空间。

cpp
short int z = 1000;  // 短整型

6.4 long

表示长整型,占用较多的内存空间。

cpp
long int big_num = 1000000;  // 长整型

7. 数据类型的大小

可以使用sizeof运算符来获取数据类型或变量占用的字节数:

cpp
std::cout << "Size of char: " << sizeof(char) << " bytes" << std::endl;
std::cout << "Size of int: " << sizeof(int) << " bytes" << std::endl;
std::cout << "Size of float: " << sizeof(float) << " bytes" << std::endl;
std::cout << "Size of double: " << sizeof(double) << " bytes" << std::endl;
std::cout << "Size of bool: " << sizeof(bool) << " bytes" << std::endl;

8. 数据类型的选择

在选择数据类型时,应考虑以下因素:

  1. 数据范围:确保所选类型能够容纳可能的最大值和最小值
  2. 内存空间:在不需要大空间时,选择较小的类型以节省内存
  3. 精度要求:对于需要高精度的计算,选择双精度浮点型
  4. 性能:某些类型的操作可能比其他类型更快

8.1 示例

  • 存储年龄:使用unsigned charunsigned short(范围足够且节省空间)
  • 存储工资:使用floatdouble(需要小数)
  • 存储大整数:使用longlong long(范围更大)

9. 类型转换

C++ 支持两种类型转换:隐式转换和显式转换。

9.1 隐式转换

编译器自动进行的类型转换:

cpp
int i = 10;
double d = i;  // int 隐式转换为 double

9.2 显式转换

程序员明确指定的类型转换:

cpp
double d = 3.14;
int i = (int)d;  // C 风格强制转换
int j = static_cast<int>(d);  // C++ 风格转换

10. auto 类型推导

C++11 引入了auto关键字,可以自动推导变量类型:

cpp
auto i = 10;           // 推导为 int
auto d = 3.14;         // 推导为 double
auto str = "hello";    // 推导为 const char*

11. decltype 类型推导

C++11 引入了decltype关键字,可以推导表达式的类型:

cpp
int x = 10;
decltype(x) y = 20;  // y 的类型与 x 相同,即 int

12. 示例:综合运用

现在,让我们看一个综合运用各种数据类型的例子:

cpp
#include <iostream>
#include <string>

// 枚举类型:月份
enum Month {
    JANUARY = 1,
    FEBRUARY,
    MARCH,
    APRIL,
    MAY,
    JUNE,
    JULY,
    AUGUST,
    SEPTEMBER,
    OCTOBER,
    NOVEMBER,
    DECEMBER
};

// 结构体类型:日期
struct Date {
    int day;
    Month month;
    int year;
};

// 类类型:学生
class Student {
private:
    std::string name;
    int id;
    float gpa;

public:
    Student(std::string n, int i, float g) : name(n), id(i), gpa(g) {}
    
    void print() {
        std::cout << "姓名: " << name << std::endl;
        std::cout << "ID: " << id << std::endl;
        std::cout << "GPA: " << gpa << std::endl;
    }
};

int main() {
    // 基本数据类型
    char grade = 'A';
    int age = 20;
    float height = 1.75f;
    double weight = 65.5;
    bool is_student = true;
    
    // 枚举类型
    Month current_month = MARCH;
    
    // 结构体类型
    Date today = {15, MARCH, 2024};
    
    // 类类型
    Student student("张三", 12345, 3.8f);
    
    // 指针类型
    int* ptr = &age;
    
    // 引用类型
    int& ref = age;
    
    // auto 类型推导
    auto num = 100;
    auto pi = 3.14159;
    
    // 输出信息
    std::cout << "成绩: " << grade << std::endl;
    std::cout << "年龄: " << age << std::endl;
    std::cout << "身高: " << height << " 米" << std::endl;
    std::cout << "体重: " << weight << " 公斤" << std::endl;
    std::cout << "是学生: " << (is_student ? "是" : "否") << std::endl;
    std::cout << "当前月份: " << current_month << std::endl;
    std::cout << "今天的日期: " << today.day << "/" << today.month << "/" << today.year << std::endl;
    std::cout << std::endl;
    student.print();
    std::cout << std::endl;
    std::cout << "指针指向的值: " << *ptr << std::endl;
    std::cout << "引用的值: " << ref << std::endl;
    std::cout << "auto 推导的类型: " << num << ", " << pi << std::endl;
    
    return 0;
}

小结

C++ 提供了丰富的数据类型,包括:

  1. 基本数据类型:整型、浮点型、字符型和布尔型
  2. 派生数据类型:数组、指针、引用、函数等
  3. 用户定义类型:类、结构体、共用体、枚举等
  4. 空类型:void

选择合适的数据类型对于编写高效、正确的程序非常重要。在后续章节中,我们将学习如何使用变量来存储这些不同类型的数据。