C++程序的基本构成
显示消息的C++程序
1 |
|
该示例包含以下元素:
- 注释,由前缀//标识。
- 预处理器编译指令#include
- 函数头:int main()
- 使用C++的cout工具显示消息的语句。
- 结束main()函数的return语句。
main()函数
1 |
|
- int main()叫做函数头。
- {}包括的部分叫做函数体:函数体指出函数应做什么计算机指令,每条完整的指令称为语句。
return 0;
称作返回语句。
作为接口的函数头
通常,C++函数可被其他函数激活或调用,函数头描述了函数与调用它的函数之间的接口。
- 位于函数名前面的部分叫作函数返回类型,它描述的是从函数返回给调用它的函数信息。
- 函数名后括号中的部分叫做形参列表或参数列表,描述的是从调用函数传递给被调用的函数的信息。
通常,main()被启动代码调用,而启动代码是由编译器添加到程序中的,是程序和操作系统之间的桥梁。
值得注意的是,在很多现有程序中,使用的是经典C函数头main()
,省略返回类型相当于说该函数的类型为int,但是,C++逐步淘汰了这种用法。
int main(void)
中void明确指出函数不接受任何参数。在C++中让括号空着与在括号中使用void等效,而C中,让括号空着表明对接收参数的行为保持沉默。
有些程序使用void main()
,并省略返回语句。这在逻辑上是一致的,因为void返回类型意味着函数不返回任何的值。该变体适用于很多系统,但由于它不是当前标准强制的一个选项,在某些系统上不能工作。
此外,ANSI/ISO C++标准允许main()函数省略返回值,默认使用return 0;
. main()的返回值并不是返回给程序的其他部分,而是返回给操作系统。通常的约定是,退出值为0则意味着程序允许成功,为非零则意味着存在问题。
为什么main()不能使用其他名称
通常,C++程序必须包含名为main()的函数。
在运行C++程序时通常从main()函数开始执行。
当然,也存在一些例外:
- Windows编程中,可以编写一个动态链接库(DLL)模块,这是其他Windows程序可以使用的代码。由于DLL模块不是独立的程序,因此不需要main()
- 有些编程环境提供一个框架程序,该程序调用一些非标准函数,如_tmain(). 在这种情况下,有一个隐藏的main(),它调用_tmain().
C++注释
C++注释以//开头。注释是程序员为读者提供的说明,编译器忽略注释。
应使用注释来说明程序,程序越复杂注释越有价值。
C++也能够识别C风格的注释,但还是以//为最佳选择。
C++预处理器和iostream文件
C++和C一样,也使用一个预处理器,该程序在进行主编译之前对源文件进行处理。
#include<iostream>
该编译指令导致预处理器将iostream文件的内容添加到程序中。这是一种典型的预处理器操作,在代码被编译之前,替换或添加文本。
iostream文件涉及程序与外部世界之间的通信,io指的是输入输出。C++的输入和输出方案设计iostream文件中的多个定义。
头文件名
像iostream这样的文件叫做包含文件,也叫头文件。C++编译器自带了很多头文件,每个头文件都支持一组特定的工具。
C语言的传统是,头文件使用拓展名h,将其作为一种通过名称表示文件类型的简单方式。
而C++头文件则没有拓展名,一些C的头文件被转换为C++头文件,这些文件被重新命名,去掉了拓展名,并在文件名称前面加上前缀c,如math.h变为cmath.
名称空间
名称空间支持是一项C++特性,旨在编写大型程序以及多个厂商现有的代码组合起来的程序时更容易,它还有有助于组织程序。
例如,不同公司的封装产品中,都包含一个叫wanda()的函数,那么我们就可以用名称空间区分使用哪个公司的wanda().
1 |
|
类、函数和变量便是C++编译器的标准组件,它们都被放置在名称空间std中。这意味着,在iostream定义的用于输出的cout变量实际上是std::cout,而endl实际上是std::endl。
为了简化代码,using编译指令应运而生。using namespsce std;
表示可以使用std名称空间中定义的名称,而不必使用std::前缀。
但需指出,上述是一种偷懒的做法,在大型项目中是一个潜在的问题。更好的方法是指明具体的变量。
1 |
|
使用cout进行C++输出
1 |
|
- 双引号括起的部分是要打印的消息,用双引号括起的一系列字符称作字符串。
- <<表示该语句将把这个字符串发送给cout,该符号指出了信息流动的路径。
- cout是一个预定的对象。
从概念上看,输出是一个流,即从程序流出的一些列字符。cout表示这种流,其属性是在iostream文件中定义的。cout的对象属性包含一个插入运算符,它可以将其右侧的信息插入到流中。
控制符endl
endl是一个特殊的C++符号,表示一个重要的概念:重起一行。
打印字符串时,cout不会自动移到下一行。
换行符
C++还提供了另一种在输出中指示换行的旧式方法:\n.
与endl不同在于,endl确保程序继续运行前刷新输出,而\n不做这样的保证。这意味着在有些系统中,有时可能在您输入信息后才会出现提示。
C++源代码的格式化
在C++中分号标示了语句的结尾。因此,在C++中,回车的作用就和空格和制表符相同。
源代码中的标记和空白
一行代码中不可分割的元素叫做标记。
通常必须使用空格、制表符或回车将两个标记分开,空格、制表符和回车统称为空白。
C++源代码风格
- 每条语句占一行。
- 每个函数都有一个开始花括号和一个结束花括号,这两个花括号各占一行。
- 函数中的语句都相对于花括号进行缩进。
- 与函数名称相关的圆括号周围没有空白。
C++语句
C++陈旭是一组函数,而每一个函数又是一组语句。
1 |
|
声明语句和变量
要将信息项存储在计算机中,必须指出信息的存储位置和所需的内存空间。在C++中使用声明语句来指出存储类型并提供位置标签。
int carrots;
提供了两项信息:需要的内存以及该内存单元的名称。
- 这条语句指出程序需要足够的存储空间来存储一个整数,在C++中用int表示整数。
- 该声明语句指出,此后程序将使用名称carrots来标识存储在该内存单元中的值。
在上述程序中,声明语句叫做定义语句,意味着将导致编译器为变量分配内存空间。在较为复杂的情况下,还可能有引用声明,这些声明命令计算机使用在其他地方定义的变量。
赋值语句
赋值语句将值赋给存储单元。
其他C++语句
1 |
|
使用cin
上面的输出表明,从键盘输入的值最终被赋给carrots.
类简介
类是用户定义的一种数据类型。要定义类需要描述:
- 它能够表示什么信息
- 它可对数据执行哪些操作
类之于对象就像类型之于变量。类描述了一种数据类型的全部属性,对象是根据这些描述创建的实体。
cout是一个ostream类对象。ostream类定义描述了ostream对象表示的数据以及可以对他执行的操作,如数字或字符串插入到输出流中。
类描述指定了可对类对象执行的所有操作,要对特定对象执行这些允许的操作,需要给该对象发送一条消息。
- 一种方式是使用类方法
- 另一种方式是重新定义运算符
函数
C++函数分两种,有返回值的和没有返回值的。
使用有返回值的函数
有返回值的函数将生成一个值,而这个值可赋给变量或在其他表达方式中使用。
C++编译器必须知道函数的参数类型和返回值类型,C++提供这种信息的方式是使用函数原型语句。
不要混淆函数原型和函数定义,原型只描述接口,而定义包含了函数的代码。
应在首次使用函数之前提供其原型,通常的做法是把原型放到main()函数定义的前面。
函数变体
有些函数需要多项信息,这些函数使用多个参数,参数间用逗号隔开。
另有一些函数不接受任何参数,可由关键字void明确指出,也可让括号为空,C++将其解释为不接受任何参数的隐式声明。
还有一些函数没有返回值,可以在原型中使用关键字void来指定返回类型。
用户定义的函数
1 |
|
函数格式
首先有一个函数头,然后是花括号中的函数体。
1 |
|
C++不允许函数定义嵌套在另一个函数定义中,每个函数定义都是独立的,所有函数的创建都是平等的。
在多函数程序中使用using编译指令
让程序能够访问名称空间std的方法有多种,下面是其中的四种:
- 将
using namespace std;
放在函数定义之前,让文件中所有函数都能够使用名称空间std中的所有元素。 - 将
using namespace std;
放在特定的函数定义中,让该函数能够使用名称空间std中的所有元素。 - 在特定的函数中使用类似
using std::cout;
这样的编译指令,而不是using namespace std;
,让该函数能够使用指定的元素,如cout - 完全不使用编译指令using,而在需要使用名称空间std中的元素时,使用前缀std::