2.1 进入C++

首先介绍一个显示消息的简单C++程序(myfirst.cpp)。

#include <iostream>                           // a PREPROCESSOR directive
int main()                                    // function header
{                                             // start of function body
    using namespace std;                      // make definitions visible
    cout << "Come up and C++ me some time.";  // message
    cout << endl;                             // start a new line
    cout << "You won't regret it!" << endl;   // more output
// If the output window closes before you can read it,
// add the following code:
    // cout << "Press any key to continue." <<endl;
	// cin.get();                                                   
    return 0;                                 // terminate main()
}                                             // end of function body
  • 注释,由前缀//标识。

  • 预处理器编译指令#include。

  • 函数头:int main()。

  • 编译指令using namespace。

  • 函数体,用{和}括起。

  • 使用C++的cout工具显示消息的语句。

  • 结束main()函数的return语句。

2.1.1 main()函数

一个程序的基本结构:

int main()
{
	statements;
	return 0;
}

很多现有的程序都使用经典C函数头:

main()

在C语言中,省略返回类型相当于说函数的类型为int。然而,C++逐步淘汰了这种用法。

也可以使用下面的变体:

int main(void)

在括号中使用关键字void明确地指出,函数不接受任何参数。在C++(不是C)中,让括号空着与在括号中使用void等效(在C中,让括号空着意味着对是否接受参数保持沉默)。有些程序员使用下面的函数头,并省略返回语句:

void main()

这在逻辑上是一致的,因为void返回类型意味着函数不返回任何值。该变体适用于很多系统,但由于它不是当前标准强制的一个选项,因此在有些系统上不能工作。因此,应避免使用这种格式,而应使用C++标准格式,这不需要做太多的工作就能完成。

最后,ANSI/ISO C++标准对那些抱怨必须在main()函数最后包含一条返回语句过于繁琐的人做出了让步。如果编译器到达main()函数末尾时没有遇到返回语句,则认为main()函数以如下语句结尾:

return 0;

这条隐含的返回语句只适用于main()函数,而不适用于其他函数。

之所以将myfirst.cpp程序中的函数命名为main(),原因是必须这样做。通常,C++程序必须包含一个名为main()的函数(不是Main()、MAIN()或mane()。记住,大小写和拼写都要正确)。由于myfirst.cpp程序只有一个函数,因此该函数必须担负起main()的责任。在运行C++程序时,通常从main()函数开始执行。因此,如果没有main(),程序将不完整,编译器将指出未定义main()函数。

存在一些例外情况。例如,在Windows编程中,可以编写一个动态链接库(DLL)模块,这是其他Windows程序可以使用的代码。由于DLL模块不是独立的程序,因此不需要main()。用于专用环境的程序——如机器人中的控制器芯片——可能不需要main()。有些编程环境提供一个框架程序,该程序调用一些非标准函数,如_tmain()。在这种情况下,有一个隐藏的main(),它调用_tmain()。但常规的独立程序都需要main(),之后讨论的都是这种程序。

2.1.2 C++注释

C++注释以双斜杠(//)打头,到行尾结束。注释可以位于单独的一行上,也可以和代码位于同一行。编译器是忽略注释的。C++也能够识别C注释,C注释包括在符号/**/之间,该注释方法可以跨越多行。

2.1.3 C++预处理器和iostream文件

如果程序要使用C++输入或输出工具,请提供这样两行代码:

#include <iostream>
using namespace std;

使用了#include编译指令,该编译指令导致预处理器将iostream文件的内容添加到程序中。这是一种典型的预处理器操作:在源代码被编译之前,替换或添加文本。编译指令导致iostream文件的内容随源代码文件的内容一起被发送给编译器。实际上,iostream文件的内容将取代程序中的代码行#include<iostream>。原始文件没有被修改,而是将源代码文件和iostream组合成一个复合文件,编译的下一阶段将使用该文件。

2.1.4 头文件名

像iostream这样的文件叫做包含文件(include file)——由于它们被包含在其他文件中:也叫头文件(header file)——由于它们被包含在文件起始处。C++编译器自带了很多头文件,每个头文件都支持一组特定的工具。C语言的传统是,头文件使用扩展名h,将其作为一种通过名称标识文件类型的简单方式。例如,头文件math.h支持各种C语言数学函数,但C++的用法变了。现在,对老式C的头文件保留了扩展名h(C++程序仍可以使用这种文件),而C++头文件则没有扩展名。有些C头文件被转换为C++头文件,这些文件被重新命名,去掉了扩展名(使之成为C+风格的名称),并在文件名称前面加上前缀c(表明来自C语言)。例如,C+版本的math.h为cmath。有时C头文件的C版本和C++版本相同,而有时候新版本做了一些修改。对于纯粹的C+头文件(如iostream)来说,去掉h不只是形式上的变化,没有h的头文件也可以包含名称空间(2.1.5)。下表对头文件的命名约定进行了总结。

头文件类型 约定 示例 说明
C++旧式风格 以.h结尾 iostream.h C++程序可以使用
C旧式风格 以.h结尾 math.h C、C++程序可以使用
C++新式风格 没有扩展名 iostream C++程序可以使用,使用namespace std
转换后的C 加上前缀c,没有扩展名 cmath C++程序可以使用,可以使用不是C的特性,如 namespace std

2.1.5 名称空间

如果使用iostream,而不是iostream.h,则应使用下面的名称空间编译指令来使iostream中的定义对程序可用:

using namespace std;

这叫做using编译指令。最简单的办法是,现在接受这个编译指令,以后再考虑它(例如,到第9章再考虑它)。但这里还是简要地介绍它。

名称空间支持是一项C++特性,旨在让您编写大型程序以及将多个厂商现有的代码组合起来的程序时更容易,它还有助于组织程序。一个潜在的问题是,可能使用两个已封装好的产品,而它们都包含一个名为wanda()的函数。这样,使用wanda()函数时,编译器将不知道指的是哪个版本。名称空间让厂商能够将其产品封装在一个叫做名称空间的单元中,这样就可以用名称空间的名称来指出想使用哪个厂商的产品。因此,Microflop Industries可以将其定义放到一个名为Microflop的名称空间中。这样,其wanda()函数的全称为Microflop::wanda();同样,Piscine公司的wanda()版本可以表示为Piscine::wanda()。这样,程序就可以使用名称空间来区分不同的版本了:

Microflop::wanda("go dancing?");
Piscine::wanda("a fish named Desire");

按照这种方式,类、函数和变量便是C++编译器的标准组件,它们现在都被放置在名称空间std中。仅当头文件没有扩展名h时,情况才是如此。这意味着在iostream中定义的用于输出的cout变量实际上是 std::cout,而endl实际上是std::endl。因此,可以省略编译指令using,以下述方式进行编码:

std::cout << "Come up and C++ me some time.";
std::cout << std::endl;

然而,多数用户并不喜欢将引入名称空间之前的代码(使用iostream.h和cout)转换为名称空间代码(使用iostream和std:cout),除非他们可以不费力地完成这种转换。于是,using编译指令应运而生。下面的一行代码表明,可以使用std名称空间中定义的名称,而不必使用std::前缀:

using namespace std;

这个using编译指令使得std名称空间中的所有名称都可用。这是一种偷懒的做法,在大型项目中存在一个潜在的问题。更好的方法是,只使所需的名称可用,这可以通过使用using声明来实现:

using std::cout;
using std::endl;
using std::cin;

用这些编译指令替换上述代码后,便可以使用cin和cout,而不必加上std::前缀。然而,要使用iostream中的其他名称,必须将它们分别加到using列表中。

2.1.6 使用cout进行C++输出

cout << "Come up and C++ me some time.";
cout << endl;

«符号表示该语句将把这个字符串发送给cout,该符号指出了信息流动的路径。cout是一个预定义对象,知道如何显示字符串、数字和单个字符等。

实际上,这演示了对象的长处之一一不用了解对象的内部情况,就可以使用它。只需要知道它的接口,即如何使用它。cout对象有一个简单的接口,如果string是一个字符串,则下面的代码将显示该字符串:

cout << string;

对于显示字符串而言,只需知道这些即可。现在来看看C++从概念上如何解释这个过程。从概念上看,输出是一个流,即从程序流出的一系列字符。cout对象表示这种流,其属性是在iostream文件中定义的。cout的对象属性包括一个插入运算符(«),它可以将其右侧的信息插入到流中。

它将字符串“Come up and C++ me some time.”插入到输出流中。因此,与其说程序显示了一条消息,不如说它将一个字符串插入到了输出流中。

如果熟悉C后才开始学习C++,则可能注意到了,插入运算符(«)看上去就像按位左移运算符(«),这是一个运算符重载的例子,通过重载,同一个运算符将有不同的含义。编译器通过上下文来确定运算符的含义。C本身也有一些运算符重载的情况。例如,&符号既表示地址运算符,又表示按位AND运算符。C++扩展了运算符重载的概念,允许为用户定义的类型(类)重新定义运算符的含义。

endl是一个特殊的C++符号,表示一个重要的概念:重起一行。在输出流中插入endl将导致屏幕光标移到下一行开头。诸如endl等对于cout来说有特殊含义的特殊符号被称为控制符(manipulator)。和cout样,endl也是在头文件iostream中定义的,且位于名称空间std中。

C++还提供了另一种在输出中指示换行的旧式方法:C语言符号\n:

cout << "What's next?\n";

\n被视为一个字符,名为换行符。

显示字符串时,在字符串中包含换行符,而不是在末尾加上endl,可减少输入量。另一方面,如果要生成一个空行,则两种方法的输入量相同,但对大多数人而言,输入endl更为方便:

cout << "n";
cout << endl;

一个差别是,endl确保程序继续运行前刷新输出(将其立即显示在屏幕上);而使用“\n”不能提供这样的保证,这意味着在有些系统中,有时可能在您输入信息后才会出现提示。

换行符是一种被称为“转义序列”的按键组合,转义序列将在第3章做更详细的讨论。

2.1.7 C++源代码的格式化

在C++中,分号标示了语句的结尾。因此,在C++中,回车的作用就和空格或制表符相同。也就是说,在C++中,通常可以在能够使用回车的地方使用空格,反之亦然。这说明既可以把一条语句放在几行上,也可以把几条语句放在同一行上。

这样虽然不太好看,但仍然是合法的代码。但也必须遵守一些规则,具体地说,在C和C++中,不能把空格、制表符或回车放在元素(比如名称)中间,也不能把回车放在字符串中间。

然而,C++11新增的原始(raw)字符串可包含回车,这将在第4章简要地讨论。

一行代码中不可分割的元素叫做标记(token)。通常,必须用空格、制表符或回车将两个标记分开,空格、制表符和回车统称为空白(white space)。有些字符(如括号和逗号)是不需要用空白分开的标记。

虽然C++在格式方面赋予了您很大的自由,但如果遵循合理的风格,程序将更便于阅读。

  • 每条语句占一行。
  • 每个函数都有一个开始花括号和一个结束花括号,这两个花括号各占一行。
  • 函数中的语句都相对于花括号进行缩进。
  • 与函数名称相关的圆括号周围没有空白。

前三条规则旨在确保代码清晰易读,第四条规则帮助区分函数和一些也使用圆括号的C++内置结构(如循环)。

2.2 C++语句

#include <iostream>

int main()
{
    using namespace std;
    
    int carrots;            // declare an integer variable
    
    carrots = 25;            // assign a value to the variable
    cout << "I have ";
    cout << carrots;        // display the value of the variable
    cout << " carrots.";
    cout << endl;
    carrots = carrots - 1;  // modify the variable
    cout << "Crunch, crunch. Now I have " << carrots << " carrots." << endl;
    // cin.get();
	return 0;
}

C++程序是一组函数,而每个函数又是一组语句。C++有好几种语句,下面介绍其中的一些。上例还提供了两种新的语句。声明语句创建变量,赋值语句给该变量提供一个值。另外,该程序还演示了cout的新功能。

2.2.1 声明语句和变量

int carrots;

这条语句提供了两项信息:需要的内存以及该内存单元的名称。具体地说,这条语句指出程序需要足够的存储空间来存储一个整数。完成的第二项任务是给存储单元指定名称。在这里,该声明语句指出,此后程序将使用名称carrots来标识存储在该内存单元中的值。Carrots被称为变量,因为它的值可以修改。在C++中,所有变量都必须声明。如果省略了声明,则当程序试图使用carrots时,编译器将指出错误。

2.2.2 赋值语句

赋值语句将值赋给存储单元。例如,下面的语句将整数25赋给变量carrots表示的内存单元:

carrots = 25;

符号=叫做赋值运算符。C++(和C)有一项不寻常的特性——可以连续使用赋值运算符。例如,下面的代码是合法的:

int steinway;
int baldwin;
int yamaha;
yamaha = baldwin = steinway = 88;

赋值将从右向左进行。首先,88被赋给steinway,然后,steinway的值(现在是88)被赋给baldwin,然后baldwin的值88被赋给yamaha。

可以对变量的值进行修改:

carrots = carrots - 1; //modify the variable

赋值运算符右边的表达式carrots-1是一个算术表达式。计算机将变量carrots的值25减去1,得到24。然后,赋值运算符将这个新值存储到变量carrots对应的内存单元中。

2.2.3 cout的新花样

如上所示,cout可用于数字和字符串。这似乎没有什么不同寻常的地方,但别忘了,整数25与字符串“25”有天壤之别。要打印字符串,cout只需打印字符串中各个字符即可。但整数25被存储为数值,计算机不是单独存储每个数字,而是将25存储为二进制数。这里的要点是,在打印之前,cout必须将整数形式的数字转换为字符串形式。另外,cout很聪明,知道carrots是一个需要转换的整数。

cout的智能行为源自C++的面向对象特性。实际上,C++插入运算符(«)将根据其后的数据类型相应地调整其行为,这是一个运算符重载的例子。在后面的章节中学习函数重载和运算符重载时,将知道如何实现这种智能设计。

可以重新定义«运算符,使cout能够识别和显示所开发的新数据类型。如果喜欢printf()提供的细致的控制功能,可以使用更高级的cout来获得相同的效果(参见第17章)。

2.3 其他C++语句

再来看几个C++语句的例子。该程序对前一个程序进行了扩展,要求在程序运行时输入一个值。为实现这项任务,它使用了cin,这是与cout对应的用于输入的对象。另外,该程序还演示了cout对象的多功能性。

int main()
{
    using namespace std;
    
    int carrots;
    
    cout << "How many carrots do you have?" << endl;
    cin >> carrots;                // C++ input
    cout << "Here are two more. ";
    carrots = carrots + 2;
// the next line concatenates output
    cout << "Now you have " << carrots << " carrots." << endl;
	// cin.get();
	// cin.get();
    return 0;
}

2.3.1 使用cin

从这条语句可知,信息从cin流向carrots。显然,对这一过程有更为正式的描述。就像C++将输出看作是流出程序的字符流一样,它也将输入看作是流入程序的字符流。iostream文件将cin定义为一个表示这种流的对象。输出时,«运算符将字符串插入到输出流中;输入时,cin使用»运算符从输入流中抽取字符。通常,需要在运算符右侧提供一个变量,以接收抽取的信息(符号«和»被选择用来指示信息流的方向)。

与cout一样,cin也是一个智能对象。它可以将通过键盘输入的一系列字符(即输入)转换为接收信息的变量能够接受的形式。在这个例子中,程序将carrots声明为一个整型变量,因此输入被转换为计算机用来存储整数的数字形式。

2.3.2 使用cout进行拼接

上述程序中一项新特性是将4条输出语句合并为一条。iostream文件定义了«运算符,以便可以像下面这样合并(拼接)输出:

cout << "Now you have " << carrots << " carrots." << endl;

这样能够将字符串输出和整数输出合并为一条语句。得到的输出与下述代码生成的相似:

cout << "Now you have "
cout << carrots; 
cout << " carrots";
cout << endl;

根据有关cout的建议,也可以按照这样的方式重写拼接版本,即将一条语句放在4行上:

cout << "Now you have"
	 << carrots
	 << " carrots."
	 << endl;

这是由于C++的自由格式规则将标记间的换行符和空格看作是可相互替换的。当代码行很长,限制输出的显示风格时,最后一种技术很方便。

2.3.3 类简介

类是用户定义的一种数据类型。要定义类,需要描述它能够表示什么信息和可对数据执行哪些操作。类之于对象就像类型之于变量。也就是说,类定义描述的是数据格式及其用法,而对象则是根据数据格式规范创建的实体。

现在来看cout。它是一个ostream类对象。ostream类定义(iostream文件的另一个成员)描述了ostream对象表示的数据以及可以对它执行的操作,如将数字或字符串插入到输出流中。同样,cin是一个istream类对象,也是在iostream中定义的。

知道类是用户定义的类型,但作为用户,并没有设计ostream和istream类。就像函数可以来自函数库一样,类也可以来自类库。ostream和istream类就属于这种情况。从技术上说,它们没有被内置到C++语言中,而是语言标准指定的类。这些类定义位于iostream文件中,没有被内置到编译器中。如果愿意,程序员甚至可以修改这些类定义,虽然这不是一个好主意(准确地说,这个主意很糟)。iostream系列类和相关的fstream(或文件I/O)系列类是早期所有的实现都自带的唯一两组类定义。然而,ANSI/ISO C++委员会在C++标准中添加了其他一些类库。另外,多数实现都在软件包中提供了其他类定义。事实上,C++当前之所以如此有吸引力,很大程度上是由于存在大量支持UNIX、Macintosh和Windows编程的类库。

类描述指定了可对类对象执行的所有操作。要对特定对象执行这些允许的操作,需要给该对象发送一条消息。例如,如果希望cout对象显示一个字符串,应向它发送一条消息,告诉它,“对象!显示这些内容!”C++提供了两种发送消息的方式:一种方式是使用类方法(本质上就是稍后将介绍的函数调用);另一种方式是重新定义运算符,cin和cout采用的就是这种方式。

2.4 函数

由于函数用于创建C++程序的模块,对C++的OOP定义至关重要,因此必须熟悉它。函数的某些方面属于高级主题,将在第7章和第8章重点讨论函数。然而,现在了解函数的一些基本特征,将使得在以后的函数学习中更加得心应手。本章剩余的内容将介绍函数的一些基本知识。

C++函数分两种:有返回值的和没有返回值的。在标准C++函数库中可以找到这两类函数的例子。下面首先来看一个有返回值的库函数,然后介绍如何编写简单的函数。

2.4.1 使用有返回值的函数

有返回值的函数将生成一个值,而这个值可赋给变量或在其他表达式中使用。例如,标准C/C++库包含一个名为sqrt()的函数,它返回平方根。假设要计算6.25的平方根,并将这个值赋给变量x,则可以在程序中使用下面的语句:

x = sqrt(6.25);

表达式sqrt(6.25)将调用sqrt()函数。表达式sqrt(6.25)被称为函数调用,被调用的函数叫做被调用函数(called function),包含函数调用的函数叫做调用函数(calling function)。圆括号中的值(这里为6.25)是发送给函数的信息,这被称为传递给函数。以这种方式发送给函数的值叫做参数。函数sqrt()得到的结果为2.5,并将这个值发送给调用函数:发送回去的值叫做函数的返回值(return value)。可以这么认为,函数执行完毕后,语句中的函数调用部分将被替换为返回的值。因此,这个例子将返回值赋给变量X。简而言之,参数是发送给函数的信息,返回值是从函数中发送回去的值。

在使用函数之前,C++编译器必须知道函数的参数类型和返回值类型。如果缺少这些信息,编译器将不知道如何解释返回值。C++提供这种信息的方式是使用函数原型语句。

函数原型之于函数就像变量声明之于变量——指出涉及的类型。例如,C++库将sqrt()函数定义成将一个(可能)带小数部分的数字(如6.25)作为参数,并返回一个相同类型的数字。有些语言将这种数字称为实数,但是C++将这种类型称为double(将在第3章介绍)。sqrt()的函数原型像这样:

double sqrt(double);

第一个double意味着sqrt()将返回一个double值。括号中的double意味着sqrt()需要一个double参数。

原型结尾的分号表明它是一条语句,这使得它是一个原型,而不是函数头。如果省略分号,编译器将把这行代码解释为一个函数头,并要求接着提供定义该函数的函数体。

在程序中使用sqrt()时,也必须提供原型。可以用两种方法来实现:

  • 在源代码文件中输入函数原型;
  • 包含头文件cmath(老系统为math.h),其中定义了原型。

第二种方法更好,因为头文件更有可能使原型正确。对于C++库中的每个函数,都在一个或多个头文件中提供了其原型。可以通过手册或在线帮助查看函数描述来确定应使用哪个头文件。例如,sqrt()函数的说明将指出,应使用cmath头文件。(同样,可能必须使用老式的头文件math.h,它可用于C和C++程序中。)

不要混淆函数原型和函数定义。可以看出,原型只描述函数接口。也就是说,它描述的是发送给函数的信息和返回的信息。而定义中包含了函数的代码,如计算平方根的代码。C和C++将库函数的这两项特性(原型和定义)分开了。库文件中包含了函数的编译代码,而头文件中则包含了原型。应在首次使用函数之前提供其原型。通常的做法是把原型放到main()函数定义的前面。下例程序演示了库函数sqrt()的用法,它通过包含cmath文件来提供该函数的原型:

#include <iostream>
#include <cmath>    // or math.h

int main()
{
    using namespace std;
   
    double area;
    cout << "Enter the floor area, in square feet, of your home: ";
    cin >> area;
    double side;
    side = sqrt(area);
    cout << "That's the equivalent of a square " << side 
         << " feet to the side." << endl;
    cout << "How fascinating!" << endl;
	// cin.get();
	// cin.get();
    return 0;
}

C++允许在程序的任何地方声明新变量,因此上述程序在要使用side时才声明它。C++还允许在创建变量时对它进行赋值。这个过程叫做初始化(initialization),将在第3章更详细地介绍。 cin知道如何将输入流中的信息转换为double类型,cout知道如何将double类型插入到输出流中。前面讲过,这些对象都很智能化。

2.4.2 函数变体

有些函数需要多项信息。这些函数使用多个参数,参数间用逗号分开。

另外一些函数不接受任何参数。

关键字void明确指出,该函数不接受任何参数。如果省略void,让括号为空,则C++将其解释为一个不接受任何参数的隐式声明。

注意,与其他一些计算机语言不同,在C++中,函数调用中必须包括括号,即使没有参数。

还有一些函数没有返回值。可以在原型中使用关键字void来指定返回类型,以指出函数没有返回值。由于它不返回值,因此不能将该函数调用放在赋值语句或其他表达式中。相反,应使用一条纯粹的函数调用语句。

在有些语言中,有返回值的函数被称为函数(function);没有返回值的函数被称为过程(procedure)或子程序(subroutine)。但C++与C一样,这两种变体都被称为函数。

2.4.3 用户定义的函数

每个C++程序都必须有一个main()函数,用户必须对它进行定义。假设需要添加另一个用户定义的函数。和库函数一样,也可以通过函数名来调用用户定义的函数。对于库函数,在使用之前必须提供其原型,通常把原型放到main()定义之前。但现在您必须提供新函数的源代码。最简单的方法是,将代码放在main()的后面。

#include <iostream>
void simon(int);    // function prototype for simon()

int main()
{
    using namespace std;
    simon(3);       // call the simon() function
    cout << "Pick an integer: ";
    int count;
    cin >> count;
    simon(count);   // call it again
    cout << "Done!" << endl;
	// cin.get();
    // cin.get();
    return 0;
}

void simon(int n)   // define the simon() function
{
    using namespace std;

    cout << "Simon says touch your toes " << n << " times." << endl;
}                   // void functions don't need return statements

simon()函数的定义与main()的定义采用的格式相同。首先,有一个函数头;然后是花括号中的函数体。注意,定义simon()的源代码位于main()的后面。和C一样(但不同于Pascal),C++不允许将函数定义嵌套在另一个函数定义中。每个函数定义都是独立的,所有函数的创建都是平等的。

可以将计算机操作系统(如UNIX或Windows)看作调用程序。因此,main()的返回值并不是返回给程序的其他部分,而是返回给操作系统。很多操作系统都可以使用程序的返回值。例如,UNIX外壳脚本和Windows命令行批处理文件都被设计成运行程序,并测试它们的返回值(通常叫做退出值)。通常的约定是,退出值为0则意味着程序运行成功,为非零则意味着存在问题。因此,如果C++程序无法打开文件,可以将它设计为返回一个非零值。然后,便可以设计一个外壳脚本或批处理文件来运行该程序,如果该程序发出指示失败的消息,则采取其他措施。

2.4.4 用户定义的有返回值的函数

我们再深入一步,编写一个使用返回语句的函数。main()函数已经揭示了有返回值的函数的格式:在函数头中指出返回类型,在函数体结尾处使用return。可以用这种形式为在英国观光的人解决重量的问题。在英国,很多浴室都以英石(stone)为单位,不像美国以磅或公斤为单位。一英石等于14磅,使用一个函数来完成这样的转换。

#include <iostream>
int stonetolb(int);     // function prototype
int main()
{
    using namespace std;
    int stone;
    cout << "Enter the weight in stone: ";
    cin >> stone;
    int pounds = stonetolb(stone);
    cout << stone << " stone = ";
    cout << pounds << " pounds." << endl;
	// cin.get();
    // cin.get();
    return 0;
}

int stonetolb(int sts)
{
     return 14 * sts;
}

函数stonetolb()短小、简单,但包含了全部的函数特性:

  • 有函数头和函数体;
  • 接受一个参数;
  • 返回一个值;
  • 需要一个原型。

可以把stonetolb()看作函数设计的标准格式。第7章和第8章将更详细地介绍函数。

2.4.5 在多函数程序中使用using编译指令

可以采用一种方法让两个函数都能够访问名称空间std,即将编译指令放在函数的外面,且位于两个函数的前面。

当前通行的理念是,只让需要访问名称空间std的函数访问它是更好的选择。例如,只有main()函数使用cout。因此没有必要让函数stonetolb()能够访问名称空间std。因此编译指令using被放在函数main()中,使得只有该函数能够访问名称空间std。

总之,让程序能够访问名称空间std的方法有多种,下面是其中的4种。

  • 将using namespace std;放在函数定义之前,让文件中所有的函数都能够使用名称空间std中所有的元素。
  • 将using namespace std;放在特定的函数定义中,让该函数能够使用名称空间std中的所有元素。
  • 在特定的函数中使用类似using std::cout;这样的编译指令,而不是using namespace std;,让该函数能够使用指定的元素,如cout。
  • 完全不使用编译指令using,而在需要使用名称空间std中的元素时,使用前缀std::,如下所示:
std::cout << "I'm using cout and endl from the std namespace" << std::endl;