1 | int main() |
关于main函数:
调用 C++ 编译器的命令因编译器和操作系统的不同而不同,常用的编译器是 GNU 编译器和微软 Visual Studio 编译器。调用 GNU 编译器的默认命令是 g++
:
1 | $ g++ prog1.cc -o prog1 |
这里的 $
是系统提示符。这个命令产生一个为 prog1 或 prog1.exe 的可执行文件。在 UNIX 系统下,可执行文件没有后缀;而在 Windows 下,后缀为 .exe
。-o prog1
是编译器参数以及用来存放可执行文件的文件名。如果省略 -o prog1
,那么编译器在 UNIX 系统下产生名为 a.out 而在 Windows 下产生名为 a.exe 的可执行文件。
微软编译器采用命令 cl
来调用:
1 | C:\directory> cl -GX prog1.cpp |
这里的 C:\directory>
是系统提示符,directory
是当前目录名。cl
是调用编译器的命令。-GX
是一个选项,该选项在使用命令行界面编译器程序时是必需的。微软编译器自动产生与源文件同名的可执行文件,这个可执行文件具有 .exe 后缀且与源文件同名。本例中,可执行文件命名为 prog1.exe。
更多的信息请参考你的编译器用户指南。
C++ 程序文件的后缀与运行的具体编译器有关。常见的形式包括:
访问main函数的返回值的方式和系统有关。不论UNIX和Windows系统,执行程序后,必须发出一个适当的echo命令。UNIX系统中,通过键入如下命令获取状态:
1 | $ echo $? |
要在Windows系统下查看状态,键入
1 | c:\directory> echo %ERRORLEVEL% |
编译器的部分工作是寻找程序代码中的错误。编译器不能查出程序的意义是否正确, 但它可以查出程序形式上的错误。下面是编译器能查出的最普遍的一些错误。
1 | // error: missing ')' in parameter |
1 |
|
程序的第一行是一个 预处理指示 :
1 |
告诉编译器要使用 iostream 库。尖括号里的名字是一个。头文件。程序使用库工具时必须包含相关的头文件。#include
指示必须单独写成一行——头文件名和 #include
必须在同一行。通常,#include
指示应出现在任何函数的外部。而且习惯上,程序的所有 #include
指示都在文件开头部分出现。
main 函数体中第一条语句执行了一个表达式。C++ 中,一个表达式由一个或几个操作数和通常是一个操作符组成。该语句的表达式使用输出操作符(<<
操作符),在标准输出上输出提示语:
1 | std::cout << "Enter two numbers:" << std::endl; |
这个语句用了两次输出操作符。每个输出操作符实例都接受两个操作数:左操作数必须是 ostream 对象;右操作数是要输出的值。操作符将其右操作数写到作为其左操作数的 ostream 对象。
C++ 中,每个表达式都会产生一个结果,通常是将操作符作用到其操作数所产生的值。当操作符是输出操作符时,结果是左操作数的值。也就是说,输出操作返回的值是输出流本身。
endl
是一个特殊值,称为 操纵符 ,将它写入输出流时,具有输出换行的效果,并刷新与设备相关联的缓冲区。通过刷新缓冲区,用户可立即看到写入到流中的输出。
细心的读者会注意到这个程序中使用的是 std::cout
和 std::endl
,而不是 cout
和 endl
。前缀 std::
表明 cout
和 endl
是定义在命名空间 std
中的。使用命名空间程序员可以避免与库中定义的名字相同而引起无意冲突。因为标准库定义的名字是定义在命名空间中,所以我们可以按自己的意图使用相同的名字。
标准库使用命名空间的副作用是,当我们使用标准库中的名字时,必须显式地表达出使用的是命名空间 std
下的名字。std::cout
的写法使用了作用域操作符(scope operator,::
操作符),表示使用的是定义在命名空间 std
中的 cout
。我们将在 第 3.1 节学习到程序中经常使用的避免这种冗长句法的方法。
在输出提示语后,将读入用户输入的数据。先定义两个名为 v1 和 v2 的 变量来保存输入:
1 | int v1, v2; |
将这些变量定义为 int 类型,int 类型是一种代表整数值的内置类型。这些变量 未初始化,表示没有赋给它们初始值。这些变量在首次使用时会读入一个值,因此可以没有初始值。
下一条语句读取输入:
1 | std::cin >> v1 >> v2; |
输入操作符(>>
操作符)行为与输出操作符相似。它接受一个 istream 对象作为其左操作数,接受一个对象作为其右操作数,它从 istream 操作数读取数据并保存到右操作数中。
C++ 中有单行注释和成对注释两种类型的注释。
//
)开头,行中处于双斜线右边的内容是注释,被编译器忽略。/* */
),是从 C 语言继承过来的。这种注释以/*
开头,以*/
结尾。编译器把落入注释对/**/
之间的内容作为注释。成对注释总是以 /*
开始并以 */
结束。这意味着,一对注释符号不能出现在另一对注释符号中。
临时忽略一段代码更好的方法,是用编辑器在要忽略的每一行代码前面插入单行注释。
旧的 C 注释语法在 C++ 里还可以用,C++新发明的行尾注释语法也有其过人之处。例如下面这种情形:
1 | if ( a > b ) { |
假设你出于某种原因要注释掉这个代码块。从软件工程的角度看,写这段代码的程序员也做得很好,他最初的代码里也写了一个注释,以解释代码在做什么。用 C++形式的句法来注释掉这个程序块时,嵌在里面的最初的注释不受影响,但如果选择 C 风格的注释就会发生严重的错误:
1 | if ( a > b ) { |
请注意嵌在代码块里的注释是怎么无意间使本来想注释掉整个代码块的注释提前结束的。
C 风格的注释当然还有它存在的价值。例如,它们在 C 和 C++ 编译器都要处理的头文件中是无法替代的。尽管如此, 只要有可能,你最好尽量用 C++ 风格的注释 。
值得指出的是,有些老的专门为 C 写的预处理程序不知道处理 C++ 风格的注释,所以象下面这种情形时,事情就不会象预想的那样:
1 |
Doxygen 是一个强大的程序文档生成工具,只要注释符合Doxygen的规范,这些注释就可以用来生成程序的文档。这里 总结了Doxygen推荐的注释风格。