【读书笔记】C++ Primer Plus:第2章 开始学习C++

第2章 开始学习C++

2.1 进入C++

cout 生成字符输出,注释以//打头,C++对大小写敏感,区分大小写。
文件扩展名cpp是一种表示C++程序的常用方式。
有些窗口环境在独立的窗口中运行程序,并在程序运行完毕后自动关闭该窗口。如要让窗口一直打开,直到按任何键,可在return语句前添加:cin.get();
C语言输入和输出
C++能使用printf()、scanf()和其他所有标准C输入和输出函数,只需要包含常规C语言的stdio.h文件。
使用函数来创建C++程序 。通常,先将程序组织为主要任务,然后设计独立的函数来处理这些任务。

//myfirst.cpp---displays a message
#include <iostream>  //预处理器编译指令 
int main()    //函数头 
{
	using namespace std;   //编译指令 
	cout <<"Come up and C++ me some time.";
	cout << endl;
	cout << "You won't regret it!" << endl;
	return 0;
}

2.1.1 main()函数

在C++中,每条完整的指令都称为语句,所有的语句都以分号结束。

  1. 作为接口的函数头
    通常,C++函数可被其他函数激活或调用,函数头描述了函数与调用它的函数音的接口,位于函数名前面的部分叫做函数返回类型。它描述的是从函数返回给调用它的函数的信息。函数名后括号中的部分叫做形参列表或参数列表,它描述的是从调用函数传递给被调用函数的信息。
    通常,mail()被启动代码调用,而启动代码是由编译器添加到程序中的,是程序和操作系统间的桥梁。
    int main()表明main()函数可给调用它的函数返回一个整数值,且不从调用它的函数那获得任何函数。
    main() 在C语言中,省略返回类型相当于说函数的类型为int,而C++淘汰了这种用法。
    int main(void) 在括号中使用关键字void明确地指出,函数不接受任何参数。在C++中,让括号空着与在括号中使用void等效,而在C中,让括号空着意味着对是否接受参数保持沉默。
    C++中如编译器到达main()函数末尾时没有遇到返回语句,则认为main()函数以如下语句结尾:
    return 0;
    这条隐含的返回语句只适用于main()函数。
  2. 为什么main()不能使用其他名称
    通常,C++程序必须包含一个名为main()的函数。存在一些例外情况,如在Windows编程中,可编写一个动态链接库DLL模块,由于DLL模块不是独立的程序,因此不需要main(),用于专用环境的程序,如机器人中的控制器芯片——可能不需要main()。有些编程环境提供一个框架程序,该程序调用一些非标准函数,如_tmain()。在这种情况下,有一个隐藏的main(),它调用_tmain()。

2.1.2 C++注释

以双斜杠//打头,到行尾结束。
C++也能识别C注释,C注释包含在符号/*和*/之间,可跨越多行。

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

#include <iostream>
C++的输入/输出方案涉及iostream文件中的多个定义,为了使用cout来显示消息,第一个程序需要这些定义。#inclide编译指令导致iostream文件中的内容随源代码文件的内容一起被发送给编译器。将原代码文件和iostream组合成一个复合文件 ,编译的下一阶段将使用该文件。
注意:使用cin和cout进行输入和输出的程序必须包含文件iostream。

2.1.4 头文件名

像iostream这样的文件叫做包含文件(include file),也叫头文件(header file)。
C++编译器自带了很多头文件,每个头文件都支持一组特定工具。
C语言的传统是:头文件使用扩展名h,C++用法变了,对老式C的头文件保留了扩展名h(C++仍可使用),而C++头文件则没有扩展名,有些C头文件被转换成C++头文件 ,这些文件 被重新命名,去掉了扩展名h,并在文件名前加上前缀c。
对于纯粹的C++头文件如iostream来说,去掉h不只是形式上的变化,没有h的头文件也可包含名称空间。
C使用不同的文件扩展名来表示不同文件类型,因此用一些特殊的扩展名(如.hpp或.hxx)表示C++头文件是有道理的,ISO一致同意不使用任何扩展名。

2.1.5 名称空间

如果使用iostream,则应使用下面的名称空间编译指令来使iostream中的定义对程序可用:
using namespace std;
这叫做using编译指令,名称空间支持是一项C++特性,在编写大型程序以及将多个厂商现有的代码组合起来的程序时更容易,它还有助于组织程序。一个潜在的问题是,可能使用两个已封装好的产品,而它们都包含一个名为wanda()的函数。名称空间让厂商能将其产品封装在一个叫做名称空间的单元中,这样就可用名称空间的名称来指出想使用哪个厂商的产品。如:Microflop Industries可将其定义放到一个名为Mixroflop的名称空间中,这样,其wanda()函数的全称为Microflop::wanda();同梓,Piscine公司的wanda()版本可表示为Piscine::wanda()。这样, 程序就可使用名称空间来区分不同的版本。
Microflop::wanda("go dancing?"); Pisicine::wanda("a first named Desire");
按照此方式,类、函数和变量便是C++编译器的标准组件,它们都被放在名称空间srs中,仅当头文件没有扩展名h 时,情况才是如此。这意味着在iostream中定义的用于输出的cout变量实际上是std::cout,endl实际上是std::endl。因此,可省略编译指令using,以下述方式编码:
std::cout << "Come up and C++ me some tine."; 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::前缀:
using namespace std;
然而,要使用iostream中的其他名称,必须将它们加到using列表中。

2.1.6 使用cout进行C++输出

cout <<"Come up and C++ me some time.";
双引号括起的部分是要打印的消息。在C++中,用双引号括起的一系列字符叫做字符串。<<符号表示该语句将把这个字符串发送给cout;该符号指出了信息流动的路径。
cout的对象属性包括一个插入运算符<<,它可将其右边的信息插入到流中。
cout << "Come up and C++ me some time.";
它将字符串"Come up and C++ me some time."插入到输出流中。
初识运算符重载:
插入运算符<<看上去就像按位左移运算符<<,这是一个运算符重载的例子,通过重载,同一个运算符将有不同的含义。编译器通过上下文来确定运算符的含义。C本身也有一些运算符重载的情况。如&符号既表示地址运算符,又表示按位AND运算符。*既表示乘法,又表示对指针解除引用。
C++扩展了运算符重载的概念,允许为用户定义的类型(类)重新定义运算符的含义。

  1. 控制符endl
    cout << endl;
    endl是一个特殊的C++符号,表示:重起一行。在输出流中插入endl将导致屏幕光标移到下一行开头。如endl等对于cout来说有特殊含义的特殊符号被称为控制符(manipulator)。和cout一样,endl也是在头文件iostream中定义的,且位于名称空间std中。
  2. 换行符
    C++还提供了另一种在输出中批示换行的旧式方法:C语言符号\n:
    cout << "What's next?\n";
    \n被视为一个字符,名为换行符。
    显示字符时,在字符串中包含换行符,可减少输入量。
    如要生成一个空行,两种方法的输入量相同,但对大多数人而言,输入endl更为方便。
    一个差别是,endl确保程序继续运行前刷新输出(将其立即显示在屏幕上),而使用“\n”不能提供这样的保证。
    换行符是一种被称为“转义序列”的按键组合。

2.1.7 C++源代码的格式化

有些语句(如FORTRAN)是面向行的,即每条语句占一行,对这些语句来说,回车的作用是将语句分开。
而C++中,分号标示了语句的结尾。因此,在C++中,回车的作用就和空格或制表符相同。也就是说,在C++中,通常可在能使用回车的地方使用空格,反之亦然。这说明既可把一条语句放在几行上,也可把几条语句放在同一行上。
规则:在C和C++中,不能把空格、制表符或回车放在元素(如名称)中间,也不能把回车放在字符串中间。
然而,C++11新增的原始(raw)字符串可包含回车。

  1. 源代码中的标记和空白
    一行代码中不可分割的元素叫做标记(token),通常,必须用空格、制表符或回车将两个标记分开,空格、制表符或回车统称为空白(white space),有些字符(如括号和逗号)是不需要用空白分开的标记。
  2. C++源代码风格
    规则:每条语句占一行
    每个函数都 有一个开始花括号和一个结束花括号,这两个花括号各占一行。
    函数中的语句都相对于花括号进行缩进。
    与函数名称相关的圆括号周围没有空白(帮助区分函数和一些也使用圆括号的C++内置结构,如循环)。

2.2 C++语句

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

//carrots.cpp---uses and displays a variable

#include <iostream>
int main()
{
	using namespace std;
	int carrots;
	carrots=25;
	cout << "I have ";
	cout << carrots;
	cout << " carrots.";
	cout <<endl;
	carrots=carrots-1;
	cout <<"Crunch,crunch.Now I have " << carrots << " carrots."<< endl;
	return 0;
}

2.2.1 声明语句和变量

要将信息项存储在计算机中,必须指出信息的存储位置和所需的内存空间。C++中,使用声明语句 来指出存储类型并提供位置标签。
int carrots;
这条语句提供了两项信息:需要的内存及该内存单元的名称。具体地说,它指出程序需要足够的存储空间来存储一个整改 。int表示整数,程序将使用名称carrots来标识存储在该内存单元中的值,Carrots被称为变量,因为它的值可修改。在C++中,所有变量都必须声明。
程序中的声明语句叫做定义声明defining declaration语句,简称为定义。
还有引用声明reference dealaration,这些声明命令计算机使用在其分地方定义的变量。通常,声明不一定是定义。
在C和Pascal中,所有的变量声明通常都位于函数或过程的开始位置,但C++没有这种限制,通常做法是,在首次使用变量前声明它。缺点:没有把所有的变量名放在一起,无法对函数使用了哪些变量一目了然。

2.2.2 赋值语句

赋值语句将值赋给存储单元。carrots = 25;
符号=叫做赋值运算符,可以连续使用赋值 运算符。
int steinway; int baldwin; int yamaha;
yamaha = baldwin = steinway = 88;
赋值将从右向左进行。首先,88被赋给steinway;然后,steinway的值被赋给baldwin;然后baldwin的值被赋给yamaha.
可对变量的值进行修改:carrots = carrots - 1;

2.2.2 cout的新花样

cout可用来打印字符串,打印变量:cout << carrots; 打印存储在carrots中的整数值,即25;
整数25和字符串“25”有天壤之别,该字符串存储的是书写该数字时使用的字符,即字符3和8要打印字符串,cout只需打印字符串中各个字符即可。但整数25被存储为数值 ,将25存储为二进制数,在打印之前,cout必须将整数形式的数字转换为字符串形式。
在C语言中,要打印字符串“25”和整数25,可使用C语言的多功能输出函数printf():
printf("Printing a string: %s\n","25"); printf("Printing an integer:%d\n,25);
cout很聪明,C++插入运算符<<将根据其后的数据类型相应地调整某行为。
cout 能够识别类型的功能表明,另外,它是可扩展的,可重新定义<<运算符,使cout能识别和显示所开发搓板 数据类型。

2.3 其他C++语句

要求在程序运行时输入一个值,使用cin。

//getinfo.cpp---input and output

#include <iostream>
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;
信息从cin流向carrots,它将输入看作是流入程序的字符流,iostream文件将cin定义为一个表示这种流的对象。符号<<和>>被选择用来指示信息流和方向。
cin也是一个智能对象,可将通过键盘输入的一系列字符(即输入)转换为接收信息的变量能接受的形式。

2.3.2 使用cout进行拼接

cout << "Now you have" << carrots << "carrots." << endl; 合并(拼接)输出,能将字符串输出和整数输出合并为一条语句。
cout << "Now you have "; cout << carrots; cout << " carrots"; cout << endl;
也可这样重写拼接版本,即将一条语句放到4行上:
cout << "Now you have " << carrots << " carrots." << endl;
这是由于C++的自由格式规则将标记间的换行符和空格看作是可相互替换的。

2.3.3 类简介

类是用户定义的一种数据类型。要定义类,需描述它能表示什么信息和可对数据执行哪些操作。类定义描述的是数据格式及其用法,对象是根据数据格式规范创建的实体。
注意:类描述了一种数据类型的全部属性(包括可使用它执行的操作),对象是根据这些描述创建的实体。
类是用户定义的类型,也可来自类库,如ostrean和istream。从技术上说,它们没有被内置在C++语言中,而是语言标准指定的类,这些类定义位于iostream文件中,没有被内置到编译器中。
类描述指定了可对类对象执行的所有操作。要对特定对象执行这些允许的操作,需要对该对象发送一条消息。C++提供了两种发送消息的方式:一种是使用类方法;另一种是重新定义运算符,cin和cout采用的就是这种方式。

2.4 函数

C++函数分两种:有返回值的和没有返回值的。

2.4.1 使用有返回值的函数

有返回值的函数将生成一个值,这个值可赋给变量或在其他表达式中使用。sqrt()的函数将返回平方根。
x= sqrt(6.25);
表达式sqrt(6.25)将调用sqrt()函数,表达式sqrt(6.25)被称为函数调用,被调用的函数叫做被调用函数called function,包含函数调用的函数叫做调用函数calling function.
圆括号中的值6.25是发送给函数的信息,这被称为传递给函数,以这种方式发送给函数的值叫做参数。
函㶢的返回值是2.5。函数执行完毕后,语句中的函数调用部分将被替换为返回的值。
参数是发送给函数的信息,返回值是从函数中发送回去的值。
在使用函数之前,C++编译器必须知道函数的参数类型和返回值类型,C++提供这种信息的方式是使用函数原型语句。
注意:C++程序应当为程序中使用的每个函数提供原型。
函数原型之于函数就像变量声明之于变量——指出涉及的类型。实数,C++将这种类型称为double。
sqrt()的函数原型像这样:
double sqrt(double);
在程序中使用sqrt()时,也必须提供原型,可以用两种方法实现:
在源代码文件中输入函数原型;包含头文件cmath(老系统为math.h),其中定义了原型。
原型只描述函数接口,它描述的是发送给函数的信息和返回的信息。定义中包含了函数的代码。C和C++将库函数的这两项特性(原型和定义)分开了,库文件中包含了函数的编译代码,头文件中包含了原型。
C++库函数存储在库文件中。C++允许在程序的任何地方声明新变量,还允许在创建变量时对它进行赋值:
double side =sqrt(area);
这个过程叫做初始化。

//sqrt.cpp---using the sqrt() function

#include <iostream>
#include <cmath>
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;
	return 0;
}

2.4.4 函数变体

数学函数pow()接受两个参数,参数间用逗号分开,返回值是以第一个参数为底、第二个参数为指数的幂。函数的原型如下:
double pow(double,double);
使用:answer=pow(5.0,8.0);
rand()函数不接受任何参数,返回一个随机整数。函数原型如下: int rand(void);
如省略void,让括号为空,则C++将其解释为一个不接受任何参数的隐式声明。使用:myGuess=rand();
C++中,函数调用中必须包括括号,即使没有参数。
还有一些函数没有返回值,可在原型中使用关键字void来指定返回类型,以指出函数没有返回值:
void bucks(double);
由于它不返回值,因此不能将该函数调用放在赋值语句或其他表达式中。相反,应用一条纯粹的函数调用语句:
bucks(1234.56);
有些语言中,有返回值的函数被称为函数,没有返回值的函数被称为过程或子程序。C++和C一样,这两种变体都称为函数。

2.4.3 用户定义的函数

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

  1. 函数格式
    simon()函数的定义与main()的定义采用的格式相同。
    type functionname(argumentlist) { statements }
    定义simon()的源代码位于main()的后面,和C一样(但不同于Pascal)。C++不允许将函数定义嵌套在另一个函数定义中。每个函数定义都是独立的,所有函数的创建都是平等的。
  2. 函数头
    simon()函数的函数头如下: void simon(int n)
    开头的void表明simon()没有返回值。简而言之,simon()的函数头表明,该函数接受一个Int参数,不返回任何值。
    int main() return 0;
    通常的约定是: 退出值为0意味着程序运行成功,为非零意味着存在问题。
    main不是关键字,是一个必不可少的函数名称。
    函数名和对象名都不能是关键字。
//ourfunc.cpp---defining your own function

#include <iostream>
void simon(int);
int main()
{
	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;
}

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

格式:在函数头中指出返回类型,在函数体结尾处使用return。

//convert.cpp---converts stone to pounds

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

int stonetolb(int sts)
{
	using namespace std;
	return 14*sts;
}

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

让两个函数都能够访问名称空间std,即将编译指令放在函数的外面,且位于两个函数的前面。
让程序能够访问名称空间std的方法有多种。
using namespace std;放在函数定义之前,让文件中所有的函数都能使用名称空间std中所有的元素。
using namespace std;放在特定的函数定义中,让函数能使用名称空间std中的所有元素。
在特定的函数中使用类似using std::cout这样的编译指令,让该函数能使用指定的函数,如cout.
完全不使用编译指令using,在需要使用名称空间std中的元素时,使用前缀std::。
命名的约定:精确、让人一目了然的个人命名约定是良好的软件工程的标志。

2.5 总结

C++程序由一个或多个被称为函数的模块组成。函数由函数头和函数体组成。函数头指出函数的返回值(如果有的话)的类型和函数期望通过参数传递给它的信息的类型。函数体由一系列位于花括号中的C++语句组成。
有多种类型的C++语句,包括下述6种。
声明语句:定义函数中使用的变量的名称和类型。
赋值语句:使用赋值运算符(=)给变量赋值。
消息语句:将消息发送给对象,激发某种行动。
函数调用:执行函数。被调用的函数执行完毕后,程序返回到函数调用语句后面的语句。
函数原型:声明函数的返回原型、函数接受的参数数量和类型。
返回语句:将一个值从被调用的函数那里返回到调用函数中。
类是用户定义的数据类型规范,它详细描述了如何表示信息及可对数据执行的操作。
对象是根据类规范创建的实体,就像简单变量是根据数据类型描述创建的实体一样。
C++提供了两个用于处理输入和输出的预定义对象(cin和cout),它们是istreamt ostream类的实例,这两个类是在iostream文件中定义的。
为ostream类定义的插入运算符(<<)使得将数据插入到输出流成为可能;为istream类定义的抽取运算符(>>)能从输入流中抽取信息。
C++可使用大量的C库函数。要使用库函数,应当包含提供该函数原型的头文件 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值