章节目录

复合数据类型简介

本节阅读量:

在前面我们介绍了基本数据类型,这是C++作为核心语言的一部分提供的基本数据类型。

到目前为止,我们已经在程序中大量使用了这些基本类型,特别是int数据类型。虽然这些基本类型对于简单的需求非常有用,但当我们开始做更复杂的事情时,它们并不能满足我们的全部需求。

例如,假设您正在编写一个数学程序来将两个分数相乘。如何在你的程序中表示分数?或许可以使用一对整数(一个用于分子,一个用于分母),如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

int main()
{
    // 第一个分数
    int num1 {};
    int den1 {};

    // 第二个分数
    int num2 {};
    int den2 {};

    // 用这个char来读取分子与分母之间的 '/'
    char ignore {};

    std::cout << "Enter a fraction: ";
    std::cin >> num1 >> ignore >> den1;

    std::cout << "Enter a fraction: ";
    std::cin >> num2 >> ignore >> den2;

    std::cout << "The two fractions multiplied: "
        << num1 * num2 << '/' << den1 * den2 << '\n';

    return 0;
}

以及该程序的运行情况:

1
2
3
Enter a fraction: 1/2
Enter a fraction: 3/4
The two fractions multiplied: 3/8

虽然该程序有效,但它为我们带来了一些需要改进的挑战。首先,每对整数只是松散地连接在一起的——除了注释和代码中如何使用它们的上下文之外,几乎没有迹象表明每个分子和分母是相关的。其次,遵循DRY(不要重复你自己)原则,我们应该创建一个函数来处理用户输入的分数(以及一些错误处理)。然而,函数只能返回单个值,那么我们如何将分子和分母返回给调用者呢?

现在想象另一种情况,您正在编写一个需要保存员工ID列表的程序。你会怎么做?您可以尝试这样的操作:

1
2
3
4
5
6
7
int main()
{
    int id1 { 42 };
    int id2 { 57 };
    int id3 { 162 };
    // 以及后续其它的id
}

但如果你有100名员工呢?首先,您需要输入100个变量名。如果你需要把它们都打印出来呢?或者将它们传递给函数?我们将会打很多很多的字。这根本无法扩展。

显然,基本类型只会让我们走到这一步。


复合数据类型

幸运的是,C++支持第二组数据类型,称为复合数据类型。复合数据类型是可以从基本数据类型(或其他复合数据类型)构造的数据类型。每个复合数据类型也有自己的唯一属性。

正如我们将在本章和以后的章节中所示,我们可以使用复合数据类型来优雅地解决我们上面提出的所有挑战。

C++支持以下复合类型:

  1. 函数
  2. 数组(Arrays)
  3. 指针类型:
    • 对象指针
    • 函数指针
  4. 指向成员类型的指针:
    • 指向成员数据的指针
    • 指向成员函数的指针
  5. 引用类型:
    • 左值引用
    • 右值引用
  6. 枚举类型:
    • 强作用域枚举
    • 若弱作用域枚举
  7. 类类型:
    • struct
    • class
    • union

您已经经常使用一种复合类型:函数。例如,考虑此函数:

1
2
3
void doSomething(int x, double y)
{
}

此函数的类型为void(int, double)。请注意,此类型由基本类型组成,使其成为复合类型。当然,函数也有自己的特殊行为(例如,可调用)。

因为这里有许多材料要涵盖,我们将在多个章节中进行讨论。在本章中,我们将介绍一些更简单的复合类型,包括左值引用和指针。下一章,我们将介绍枚举类型以及struct。然后,在后面的章节中,我们将介绍class类型并深入研究一些更有用的数组类型。比如我们之前学习的std::string,它实际上是一种class类型!

我们走吧!


11.9 第11章总结

上一节

12.1 值类别(左值 lvalue 和右值 rvalue)

下一节