第 2 章 开始学习 C++
2.1 进入 C++
/*第一个C++程序*/
#include <iostream>
using namespace std; /*定义一个可视化*/
int main(void)
{
cout<<"Come up an C++"<<endl;
cout<<"You won't regret it"<<endl;
return 0;
}
使用函数来创建 C++程序。通常,先将程序组织为主要任务,然后设计独立的函数来处理这些任务。程序中的示例非常简单,只包含一个名为 main( )的函数。myfirst.cpp 示例包含下述元素。
- 注释,由前缀//标识。
- 预处理器编译指令#include。
- 函数头:int main( )。
- 编译指令 using namespace。
- 函数体,用{和}括起。
- 使用 C++的 cout 工具显示消息的语句。
- 结束 main( )函数的 return 语句。
2.1.1 main( )
int main(void)
{
statement
return 0;
}
这几行表明有一个名为 main( )的函数,并描述了该函数的行为。这几行代码构成了函数定义(function definition)。该定义由两部分组成:第一行 int main( )叫函数头(function heading),花括号({和})中包括的部分叫函数体。图 2.1 对 main( )函数做了说明。函数头对函数与程序其他部分之间的接口进行了总结;函数体是指出函数应做什么的计算机指令。在 C++中,每条完整的指令都称为语句。所有的语句都以分号结束,因此在输入示例代码时,请不要省略分号。
C++句法要求 main( )函数的定义以函数头 int main( )开始。main( )中最后一条语句叫做返回语句(return statement),它结束该函数。
通常,C++函数可被其他函数激活或调用,函数头描述了函数与调用它的函数之间的接口。位于函数名前面的部分叫做函数返回类型,它描述的是从函数返回给调用它的函数的信息。函数名后括号中的部分叫做形参列表(argument list)或参数列表(parameter list)。
通常,main( )被启动代码调用,而启动代码是由编译器添加到程序中的,是程序和操作系统(UNIX、Windows 7 或其他操作系统)之间的桥梁。
C++函数可以给调用函数返回一个值,这个值叫做返回值(return value)。在这里,从关键字 int 可知,main( )返回一个整数值。接下来,是空括号。通常,C++函数在调用另一个函数时,可以将信息传递给该函数。括号中的函数头部分描述的就是这种信息。在这里,空括号意味着 main( )函数不接受任何信息,或者 main( )不接受任何参数。在括号中使用关键字 void 明确地指出,函数不接受任何参数。
如果编译器到达 main( )函数末尾时没有遇到返回语句,则认为 main( )函数以如下语句结尾:return 0;这条隐含的返回语句只适用于 main( )函数,而不适用于其他函数。
为什么 main( )不能使用其他名称?
通常,C++程序必须包含一个名为 main( )的函数(不是 Main( )、MAIN( )或 mane( )。记住,大小写和拼写都要正确)。由于 myfirst.cpp 程序只有一个函数,因此该函数必须担负起 main( )的责任。在运行 C++程序时,通常从 main( )函数开始执行。因此,如果没有 main( ),程序将不完整,编译器将指出未定义 main( )函数。
2.1.2 C++注释
C++中的注释以 双斜杠(//)
打头。以行尾
作为结束。
注释的作用:为程序提供解释说明,使得程序通俗易懂。
通常标识程序的一部分或者是标识代码的某个方面。
注意点:编译器不会运行,会直接忽略注释。
C++也可以识别 C 语言的注释
C 语言风格的注释
多行注释
:符号/*
和*/
之间,以*/
作为注释的结束。单行注释
:以双斜杠(//)
开始,行尾
作为结束。
2.1.3 C++预处理器和 iostream 文件
如果程序要使用 C++输入或输出工具时,必须使用两行代码:
#include <iostream>
using namespace std;
使用了 #include
作为了预编译指令,也就是所谓的预处理器指令。
预处理器的操作:在源代码被编译之前,替换或添加文本。
#include <iostream>
该编译指令导致预处理器将 iostream 文件的内容添加到程序中。这是一种典型的预处理器操作:在源代码被编译之前,替换或添加文本。
2.1.4 头文件名
像 iostream 这样的文件叫做包含文件(include file)—由于它们被包含在其他文件中;也叫头文件(header file)—由于它们被包含在文件起始处。
头文件命名约定
头文件类型 | 约定 | 示例 | 说明 |
---|---|---|---|
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 名称空间(namespace)
如果使用 iostream,而不是 iostream.h,则应使用下面的名称空间编译指令来使 iostream 中的定义对程序可用:
using namespace std;
这叫做 using 编译指令。名称空间支持是一项 C++特性,旨在让您编写大型程序以及将多个厂商现有的代码组合起来的程序时更容易,它还有助于组织程序。
2.1.6 使用 cout 进行 C++输出
cout<<"Come up an C++"<<endl;
cout<<"You won't regret it"<<endl;
双引号括起的部分是要打印的消息。在 C++中,用双引号括起的一系列字符叫做字符串,因为它是由若干字符组合而成的。<<符号表示该语句将把这个字符串发送给 cout;该符号指出了信息流动的路径。cout 是什么呢?它是一个预定义的对象,知道如何显示字符串、数字和单个字符等。
从概念上看,输出是一个流,即从程序流出的一系列字符。cout 对象表示这种流,其属性是在 iostream 文件中定义的。cout 的对象属性包括一个插入运算符(<<),它可以将其右侧的信息插入到流中。
2.1.7 C++源代码的格式化
C++中源代码的风格遵循以下规则:
- 每条语句各占一行。
- 每个函数都有一个
开始花括号
和一个结束花括号
,两个花括号各占一行。 - 函数中的语句都相对于花括号进行缩进。
- 与函数名称相关的
圆括号周围没有空白
。
2.2 C++语句
#include<iostream>
using namespace std;
int main()
{
int carrots; // 声明一个整型变量
carrots = 25; // 给变量赋值
cout<<"我有 "<<carrots<<" 个carrots."<<endl;
carrots = carrots - 1; // 对变量进行修改
cout<<"快看!快看!现在,我有 "<<carrots<<" 个carrots!"<<endl;
return 0;
}
2.2.1 声明语句和变量
计算机是一种精确的、有条理的机器。要将信息项存储在计算机中,必须指出信息的存储位置和所需的内存空间。在 C++中,完成这种任务的一种相对简便的方法,是使用声明语句来指出存储类型并提供位置标签。
int carrots;
这条语句提供了两项信息:需要的内存以及该内存单元的名称。
在 C++中,首次使用变量时,必须声明
。可以避免因拼写错误而难以发现错误。声明通常指出要存储的数据类型和程序对存储在内存里的数据使用的名称。程序中的声明语句叫作定义声明
语句,简称定义
。定义会使得编译器为变量分配内存
。
程序中的声明语句叫做定义声明(defining declaration)语句,简称为定义(definition)。这意味着它将导致编译器为变量分配内存空间。
在 C 和 Pascal 中,所有的变量声明通常都位于函数或过程的开始位置,但 C++没有这种限制。实际上,C++通常的做法是,在首次使用变量前声明它。这样,就不必在程序中到处查找,以了解变量的类型。
2.2.2 赋值语句
赋值语句将值赋给存储单元。例如,下面的语句将整数 25 赋给变量 carrots 表示的内存单元:
carrots = 25; // 给变量赋值
符号=叫做赋值运算符。C++(和 C)有一项不寻常的特性—可以连续使用赋值运算符。例如,下面的代码是合法的:
2.2.3 cout 的新花样
cout << carrots;
程序没有打印“carrots”,而是打印存储在 carrots 中的整数值,即 25。实际上,这将两个操作合而为一了。首先,cout 将 carrots 替换为其当前值 25;然后,把值转换为合适的输出字符。
cout 的智能行为源自 C++的面向对象特性。实际上,C++插入运算符(<<)将根据其后的数据类型相应地调整其行为,这是一个运算符重载的例子。
2.3 其他 C++语句
2.3.1 cin 和 cout
int main()
{
using namespace std;
int carrots;
cout << "How many carrots do you have?" << endl;
cin >> carrots;
cout << "Here are two more. ";
carrots = carrots + 2;
cout << "Now you have " << carrots << "carrots." << endl;
return 0;
}
2.3.1 使用 cin
cin >> carrots;
上面的输出表明,从键盘输入的值(12)最终被赋给变量 carrots。从这条语句可知,信息从 cin 流向 carrots。它也将输入看作是流入程序的字符流。iostream 文件将 cin 定义为一个表示这种流的对象。输出时,<<运算符将字符串插入到输出流中;输入时,cin 使用>>运算符从输入流中抽取字符。
2.3.2 使用 cout 进行拼接
cout << "Now you have " << carrots << "carrots." << endl;
这样能够将字符串输出和整数输出合并为一条语句。
2.3.3 类简介
类是 C++ 面向对象编程(OOP)
的核心概念之一。
什么是类?
类是用户定义的一种数据类型。
要定义类,需要描述它能够表示什么信息
和可对数据执行什么操作
。
类定义描述的是:数据格式
及其用法
,而对象
则是根据数据格式规范
创建的实体
。
两个类cin类
和 cout类
cin
类:istream类对象
cout
类:ostream类对象
,ostream类定义
描述了ostream对象
表示的数据
以及对它执行的操作
。
2.4 函数
C++函数分两种:有返回值的和没有返回值的。
2.4.1 使用有返回值的函数
有返回值的函数将生成一个值,而这个值可赋给变量或在其他表达式中使用。
- 被调用函数:被调用的函数
- 调用函数:包含调用的函数
- 返回值:发送回的值
函数执行完毕后,语句中的函数调用部分将被替换为返回的值。
参数是发送给函数的信息,返回值是从函数中发送回去的值。
在使用函数之前,C++编译器必须知道函数的参数类型和返回值类型。
C++程序应当为程序中使用的每个函数提供原型。
函数原型之于函数就像变量声明之于变量—指出涉及的类型。
在程序中使用 sqrt( )时,也必须提供原型。可以用两种方法来实现:
- 在源代码文件中输入函数原型;
- 包含头文件 cmath(老系统为 math.h),其中定义了原型。
第二种方法更好,因为头文件更有可能使原型正确。
不要混淆函数原型和函数定义。可以看出,原型只描述函数接口。也就是说,它描述的是发送给函数的信息和返回的信息。而定义中包含了函数的代码,如计算平方根的代码。
应在首次使用函数之前提供其原型。通常的做法是把原型放到 main( )函数定义的前面。
2.4.2 函数实体
有些函数需要多项信息。这些函数使用多个参数,参数间用逗号分开。例如,数学函数 pow( )接受两个参数,返回值为以第一个参数为底,第二个参数为指数的幂。
double pow(double,double);
另外一些函数不接受任何参数。关键字 void 明确指出,该函数不接受任何参数。如果省略 void,让括号为空,则 C++将其解释为一个不接受任何参数的隐式声明。
int rand(void);
可以这样使用该函数:
myGuess = rand();
注意,与其他一些计算机语言不同,在 C++中,函数调用中必须包括括号,即使没有参数。
还有一些函数没有返回值。
void bucks(double);
由于它不返回值,因此不能将该函数调用放在赋值语句或其他表达式中。相反,应使用一条纯粹的函数调用语句:
bucks(1234.56);
在有些语言中,有返回值的函数被称为函数(function);没有返回值的函数被称为过程(procedure)或子程序(subroutine)。但 C++与 C 一样,这两种变体都被称为函数。
2.4.3 用户定义的函数
对于库函数,在使用之前必须提供其原型,通常把原型放在 main()定义之前。
- 函数格式 函数格式为:
一个函数头 + 花括号的函数体
。
#include <iostream>
void simon(int);
int mian()
{
using namespace std;
simon(3);
cout << "Pick an integer: ";
int count;
cin >> count;
simon(count);
cout << "Done!" << endl;
return 0;
}
void simon(int n)
{
using namespace std;
cout << "Simon says touch your toes " << n << "times." << endl;
}
1.函数格式
simon( )函数的定义与 main( )的定义采用的格式相同。首先,有一个函数头;然后是花括号中的函数体。可以把函数的格式统一为如下的情形:
type functionname(arguementlist)
{
statements
}
注意,定义 simon( )的源代码位于 main( )的后面。和 C 一样(但不同于 Pascal),C++不允许将函数定义嵌套在另一个函数定义中。每个函数定义都是独立的,所有函数的创建都是平等的。
2.函数头
simon( )函数的函数头如下:
void simon(int n)
开头的 void 表明 simon( )没有返回值,因此调用 simon( )不会生成可在 main( )中将其赋给变量的数字。因此,第一个函数调用方式如下:
simon(3);
由于 simon( )没有返回值,因此不能这样使用它:
simple = simon(3);
2.4.4 用户定义的有返回值的函数
我们再深入一步,编写一个使用返回语句的函数。main( )函数已经揭示了有返回值的函数的格式:在函数头中指出返回类型,在函数体结尾处使用 return。
// convert.cpp -- converts stone to pounds
#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;
}
在 main( )中,程序使用 cin 来给整型变量 stone 提供一个值。这个值被作为参数传递给 stonetolb( )函数,在该函数中,这个值被赋给变量 sts。然后,stonetolb( )用关键字 return 将 14*sts 返回给 main( )。这表明 return 后面并非一定得跟一个简单的数字。这里通过使用较为复杂的表达式,避免了创建一个新变量,将结果赋给该变量,然后将它返回。
有返回值的函数,使用关键字return
来提供返回值,并结束函数。
函数的特性
- 有函数头和函数体
- 接受一个参数
- 返回一个值
- 需要一个原型
2.4.5 在多函数程序中使用 using 编译指令
让程序访问名称空间 std 的 4 种方法
- 将
using namespace std;
放在函数定义之前
,让文件种所有的函数都能够使用名称空间std
中所有的元素。 - 将
using namespace std;
放在特定的函数定义之前
,让该函数能够使用名称空间std中
的所有元素。 - 在特定的函数中使用类似
using std::cout
;编译命令,而不是using namespace std;
让该函数能使用指定的元素,如 cout。 - 完全不使用
编译指令using
,而在需要使用名称空间std
中的元素是,使用前缀std::
。
2.5 总结
C++程序由一个或多个被称为函数的模块组成。程序从 main( )函数(全部小写)开始执行,因此该函数必不可少。函数由函数头和函数体组成。函数头指出函数的返回值(如果有的话)的类型和函数期望通过
参数传递给它的信息的类型。函数体由一系列位于花括号({})中的 C++语句组成。
有多种类型的 C++语句,包括下述 6 种。
- 声明语句:定义函数中使用的变量的名称和类型。
- 赋值语句:使用赋值运算符(=)给变量赋值。
- 消息语句:将消息发送给对象,激发某种行动。
- 函数调用:执行函数。被调用的函数执行完毕后,程序返回到函数
- 调用语句后面的语句。
- 函数原型:声明函数的返回类型、函数接受的参数数量和类型。
- 返回语句:将一个值从被调用的函数那里返回到调用函数中。
类是用户定义的数据类型规范,它详细描述了如何表示信息以及可对数据执行的操作。对象是根据类规范创建的实体,就像简单变量是根据数据类型描述创建的实体一样。
C++提供了两个用于处理输入和输出的预定义对象(cin 和 cout),它们是 istream 和 ostream 类的实例,这两个类是在 iostream 文件中定义的。为 ostream 类定义的插入运算符(<<)使得将数据插入到输出流成为可能;为 istream 类定义的抽取运算符(>>)能够从输入流中抽取信息。cin 和 cout 都是智能对象,能够根据程序上下文自动将信息从一种形式转换为另一种形式。
C++可以使用大量的 C 库函数。要使用库函数,应当包含提供该函数原型的头文件。