【硬着头皮啃C++ Primer】第1章 开始

第1章 开始

  早已听说C++Primer的大名,可一直没时间去拜读。趁这个假期,来拜会一下这本神书。我会将这本书的重点记录下来,和大家分享。

1.1 编写一个简单的C++程序

  一个函数的定义包括四个部分:返回类型、函数名、一个括号包围的形参列表以及函数体。
  每个C++程序都必须有一个或多个函数,其中必须有一个命名为main。main函数的返回值类型必须为int。

1.2 初识输入与输出

  C++语言并未定义任何输入与输出语句,它包含一个全面的标准库来提供IO机制。我们通常使用iostream库来进行输入与输出。这个库包含两个基础类型:istream和ostream,分别表示输入流和输出流。一个流就是一个字符序列。这两个类型对应四个IO对象。其中,cin为istream类型的对象,也被称为标准输入。cout为ostream类型的对象,也被称为标准输出。还有两个ostream类型的对象,clog和cerr,前者用于输出一般性信息,后者用于输出警告和错误信息。后者也被称为标准错误。
  系统通常将程序所运行的窗口和这些对象相关联,因此,当我们读取cin,就是从程序正在运行的窗口中读入信息;当我们将数据写入cout等,就是将信息输出到窗口。
  这里纠正了我之前没有正式学过C++时的一个误区:我之前用C++,倒不如说是就是用C加上STL,那时我就认为cin和cout是俩指令,类似for啊while等等,用于输入和输出,代替scanf和printf的。但是现在才知道,这是俩对象,也就是和int a里面的a是一个意思。它能够实现输入和输出,很大程度上是靠它和>>、<<实现的,而不是我之前简单的认为就是调用一个指令罢了。
  这里的<<叫做输出运算符,相对应的,>>叫做输入运算符。既然它们是运算符,那么就一定有运算对象,这里规定输出运算符<<的左侧必须是一个ostream类型的值,一般就是cout;右侧是我们想要打印的值。这个运算符的功能就是把想要打印的值写入到ostream中,输出运算符的计算结果就是其左侧计算对象。这句话看起来是废话,但在理解下面这句代码时候很有用:

std::cout<<"Enter two numbers:"<<std::endl;

  我们都写过许多与之类似的代码,但是其原理可能并不很清楚,我就只知道这个输出几句输出几个变量时很方便,但到底为什么也没注意过。
  实际上,上面这句代码可以加上如下所示的括号:

(std::cout<<"Enter two numbers:")<<std::endl;

  什么意思呢?就是说,既然<<是一个运算符,那么自然有运算顺序,运算顺序就是从左到右,首先计算cout和"Enter"这一句,将"Enter"写入cout,结果就是cout,然后再将endl写入cout。由于“<<的计算结果是其左侧的计算对象”同时“<<的计算顺序是从左往右”,因此我们才能够一个接一个的输出。
  这里的endl我平时都是懒得写的——不知道它有什么用,不加也没见程序出什么错,那就不加了。这个玩意叫做操纵符,它的用途是结束当前行,并把设备关联的缓冲区的内容刷新到设备中。这个东西是确保所有程序的输出结果都能显示在屏幕上的:因为输出的原理是“程序计算输出结果,放进缓冲区,从缓冲区拿数据写入输出流”,那么就存在这样一种情况:我缓冲区中的内容没等全写入输出流,程序就崩溃了,那么输出就会缺失,这会导致错误。加上这个操纵符,只要这一句运行完,就能保证缓冲区的所有内容全被写入输出流。缓冲区:我被输出流榨干了= =。
  再来看这个std::,这是说明cout和endl是定义在名为std的命名空间中。命名空间主要为了防止我们起名出现冲突。就像我喊“萧炎~”,可能大家一脸懵逼,萧炎谁啊?我要是喊“斗破苍穹::萧炎”,大家就明白了,我喊的是斗破苍穹这个命名空间里面的萧炎。这里的::也是一个运算符,叫做作用域运算符。
  与<<类似,>>要求其左侧是一个istream类型的运算对象,接受一个对象作为其右侧的对象。这个运算符的作用是从istream中读入数据,并保存在其右侧的对象中。它也返回其左侧对象作为运算结果。这里有一个问题:ostream我们可以自己控制什么时候向其写入的结束时刻,istream向对象写入数据怎么判断结束呢?一般用空格,回车什么的隔断就行了。比如下面一句:

std::cin>>v1>>v2;

  就可以看做首先将cin的用空格隔开的第一部分写入v1,然后返回cin的剩余部分,再写入v2。

1.3 注释简介

  C++中有两种注释:单行注释和界定符对注释。单行注释以双斜线//开始,以换行符结束。这种注释可以包含任意文本,包括额外的双斜线。
  界定符对指的是/* 和 */,这种注释可以包含多行,以 /*开始,以*/结束,可以包含除了*/以外的所有文本。当这类注释跨过多行时,约定俗成的,在每一行的开头加上一个*。下面来看练习1.8:

#include <iostream>
int main()
{
	std::cout << "/*";
	std::cout<<"*\";
	std::cout<</*"*/"*/;
	std::cout<</*"*/"/*"/*"*/;	
}

在这四句中,只有第一句和第四句能正常运行,输出“/*”,剩下三句都拉了跨。第二句,由于“\”是转义字符,因此它将后面的右引号进行了转义,这样就没有右引号和之前的左引号匹配了,会报错“缺少右引号”。第三句中,出现了完整的界定符对,中间夹着左引号,那么不看注释,剩下的就是

std::cout<<"*/;

同样是缺少右引号。第四句最后会输出“/*”,这里需要仔细来看:
首先,开始的一对界定符将一个引号注释掉,然后,后面的一对界定符将后面的引号注释掉,即

std::cout<<"/*";

那么剩下的就是一对引号包裹着的/*了。这里我的错误在于,以为这里的第二个“/*”对应最后的“*/”,实际上,与最后的*/对应的是离它最近的左边的/*,也就是说,上面那句话还不够严密,应该这样说“界定符对的注释,以/*开始,可以包含除了/*和*/以外的所有文本,如果出现第二个/*,那么第一个/*就无效了。”

1.4 控制流

  这一节中只有一个地方需要注意,就是我们想要实现读取数量不定的输入数据,其实这在PAT中已经遇到过若干次,在这里使用更加C++的风格来解决这一问题。代码如下:

int value=0;
while(std::cin>>value)
...

这里使用的判断条件为cin>>value的运行结果,我们在之前说过,这一表达式的运行结果就是cin本身,也就是说,while就是检查cin。怎么检查呢?
  当我们使用一个istream对象作为判断条件时,其效果就是检测流的状态,如果流是有效的,也就是说流未遇到错误,那么就检测成功。如果遇到文件结束符(EOF)或者输入与写入对象不符,那么就检测失败。在windows中,输入EOF是ctrl+Z,然后enter,在linux中则是ctrl+D。

1.5 类简介

  你看它自己也说了简介,那么这里就没什么太多有用的东西,也是仅有几点要注意:首先就是使用include时,后面用尖括号<>还是双引号"",规定属于标准库的头文件使用尖括号,不属于标准库的头文件使用双引号。其次是我们可以使用文件重定向来代替窗口的输入和输出,简而言之就是从窗口输入改为从文件读入,在窗口显示改为写入到文件。最后就是一件好玩的事:调用函数时,函数名后面的()也是运算符,称为调用运算符,它里面放的是实参。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值