程序的结构

基本的程序结构

学习编程语言的最好方法是编写程序。通常,初学者编写的第一个程序是一个名为“Hello World”的程序,它只是将“Hello World”打印到计算机屏幕上。虽然它非常简单,但它包含了 C++ 程序所具有的所有基本组件:

1
2
3
4
5
6
// my first program in C++
#include <iostream>
int main()
{
std::cout << "Hello World!";
}

编辑和在线运行

让我们逐行检查这个程序:

第 1 行: // my first program in C++


两个斜杠表示该行的其余部分是程序员插入的注释,但对程序的行为没有影响。程序员使用它们来包含有关代码或程序的简短解释或占位。在本例中,它是对该程序的简短介绍性描述。

第 2 行: #include < iostream >

以井号 ( # ) 开头的行是由所谓的预处理器读取和解释的指令。它们是在程序本身编译开始之前解释的特殊行。在本例中,指令 #include < iostream > 指示预处理器包含一段标准 C++ 代码(称为标头 iostream),它允许执行标准输入和输出操作,例如写入此程序的输出( Hello World )到屏幕。

第 3 行:空行。

空行对程序没有影响。它们只是提高了代码的可读性。

第 4 行: int main ()

该行是主函数的声明。本质上,函数是一组被赋予名称的代码语句:在本例中,这为后面的代码语句组命名为“main”。函数将在后面的章节中详细讨论,但本质上,它们的定义是通过一系列类型( int )、名称( main )和一对括号来引入的( () ),可以选择包含参数。

名为 main 的函数是所有C++程序中的特殊函数;它是程序运行时调用的函数。所有 C++ 程序的执行都从 main 函数开始,无论该函数实际位于代码中的哪个位置。

第 5 行和第 7 行: { 和 }

第 5 行的左大括号 ({) 表示 main 函数定义的开始,第 7 行的右大括号 (}) 表示其函数定义结尾。这些大括号之间的所有内容都是函数的主体,定义了调用 main 时发生的情况。所有函数都使用大括号来指示其定义的开始和结束。

第 6 行: std::cout << “Hello World!”;

此行是 C++ 语句。语句是实际上可以产生某种效果的表达式。它是程序的核心,指定其实际行为。语句的执行顺序与它们在函数体内出现的顺序相同。

该语句由三部分组成:首先是 std::cout ,它标识标准字符输出设备(通常是计算机屏幕)。其次,插入运算符( << ),它指示将后面的内容插入到 std::cout 中。最后,引号内的一句话(“Hello world!”)是插入到标准输出的内容。

请注意,该语句以分号 ( ; ) 结尾。这个字符标志着语句的结束,就像英语中句号结束句子一样。所有 C++ 语句都必须以分号字符结尾。 C++ 中最常见的语法错误之一是忘记以分号结束语句。

您可能已经注意到,在执行代码时,并非该程序的所有行都执行操作。有一行包含注释(以 // 开头)。有一行包含预处理器指令(以 # 开头)。有一行定义了一个函数(在本例中是主函数)。最后,一行以分号结尾的语句(插入到 cout 中),该语句位于 main 函数的大括号 ( { } ) 分隔的块内。

该程序采用不同的行结构并适当缩进,以便阅读它的人更容易理解。但 C++ 对于缩进或如何将指令拆分为不同行没有严格的规则。例如,代替

1
2
3
4
int main ()
{
std::cout << " Hello World!";
}

我们也可以写成:

1
int main () { std::cout << "Hello World!"; }

所有这些都在一行中,这与前面的代码具有完全相同的含义。

在 C++ 中,语句之间的分隔是用结束分号 ( ; ) 指定的,为此目的,分隔成不同的行根本不重要。许多语句可以写在一行中,或者每个语句可以写在自己的行中。将代码划分为不同的行只是为了使其对于可能阅读它的人来说更加清晰和示意性,但对程序的实际行为没有影响。

现在,让我们向第一个程序添加一条附加语句:

1
2
3
4
5
6
7
8
// my second program in C++
#include <iostream>

int main ()
{
std::cout << "Hello World! ";
std::cout << "I'm a C++ program";
}

编辑和在线运行

在本例中,程序在两个不同的语句中对 std::cout 执行了两次插入。再一次,不同代码行的分离只是为程序提供了更好的可读性,因为 main 可以通过这种方式完全有效地定义:

1
int main () { std::cout << " Hello World! "; std::cout << " I'm a C++ program "; }

源代码也可以分为更多代码行:

1
2
3
4
5
6
7
int main ()
{
std::cout <<
"Hello World!";
std::cout
<< "I'm a C++ program";
}

结果又与前面的示例完全相同。

预处理器指令(以 # 开头的指令)不符合此一般规则,因为它们不是语句。它们是在正确编译开始之前由预处理器读取和处理的行。预处理器指令必须在其自己的行中指定,并且由于它们不是语句,因此不必以分号 ( ; ) 结尾。

注释

如上所述,注释不会影响程序的运行;然而,它们提供了一个重要的工具,可以直接在源代码中记录程序的功能及其操作方式。

C++ 支持两种注释代码的方式:

1
2
// line comment
/* block comment */

第一个称为行注释,它会丢弃从一对斜杠符号 ( // ) 到同一行末尾的所有内容。第二个称为块注释,它丢弃 / 字符和 / 字符第一次出现之间的所有内容,并可能包含多行。

让我们向第二个程序添加注释:

1
2
3
4
5
6
7
8
9
10
/* my second program in C++
with more comments */

#include <iostream>

int main ()
{
std::cout << "Hello World! "; // prints Hello World!
std::cout << "I'm a C++ program"; // prints I'm a C++ program
}

编辑和在线运行

如果程序的源代码中包含注释而不使用注释字符组合 // 、 // ,则编译器会将它们视为 C++表达式,很可能导致编译失败并显示一条或多条错误消息。

使用命名空间std

如果您以前看过 C++ 代码,您可能已经看到使用 cout 而不是 std::cout 。两者都命名相同的对象:第一个使用其非限定名称( cout ),而第二个直接在命名空间 std 中限定它(如 std::cout )。

cout 是标准库的一部分,标准 C++ 库中的所有元素都在所谓的命名空间内声明:命名空间 std 。

为了引用 std 命名空间中的元素,程序应该限定库元素的每次使用(正如我们通过在 cout 前面加上 std::)

1
using namespace std;

上述声明允许以非限定方式访问 std 命名空间中的所有元素(没有 std:: 前缀)。

考虑到这一点,可以重写最后一个示例,以不合格地使用 cout ,如下所示:

1
2
3
4
5
6
7
8
9
// my second program in C++
#include <iostream>
using namespace std;

int main ()
{
cout << "Hello World! ";
cout << "I'm a C++ program";
}

访问 std 命名空间元素的两种方法(显式限定和 using 声明)在 C++ 中都是有效的,并且产生完全相同的行为。为了简单起见并提高可读性,这些教程中的示例将更频繁地使用后一种通过using 声明的方法,但请注意,显式限定是保证永远不会发生名称冲突的唯一方法。

命名空间将在后面的章节中更详细地解释。