`

《C++ Primer中文版》(第四版)信息汇总(二)

 
阅读更多

本章主要对语句、函数、标准IO库进行汇总。

六、语句
C++语言既有只完成单一任务的简单语句,也有作为一个单元执行的由一组语句组成的复合语句。本章主要讲解讨论C++支持的语句。

1、break语句用于结束最近的while、do while、for或switch语句,并将程序的执行权传递给紧接在被终止语句之后的语句。

2、continue语句导致最近的循环语句的当次迭代提前结束。

3、C++的异常处理包括:throw表达式、try块、由标准库定义的一组异常类。

4、使用预处理器进行调试:$ cc -DNDEBUG main.c

同时还提供了四种在调试时非常有用的常量。

view plaincopy to clipboardprint?
if(word.size()<threshold)
cerr<<"Error:"<<__FILE__ //文件名
<<":line "<<__LINE__<<endl //当前行号
<<" Compiled on"<<__DATE__ //文件被编译的日期
<<"at"<<__TIME__<<endl //文件被编译的时间
<<" Word read was"<<endl
if(word.size()<threshold)
cerr<<"Error:"<<__FILE__ //文件名
<<":line "<<__LINE__<<endl //当前行号
<<" Compiled on"<<__DATE__ //文件被编译的日期
<<"at"<<__TIME__<<endl //文件被编译的时间
<<" Word read was"<<endl

5、另一个调试技术是使用NDEBUG预处理变量以及assert预处理宏。assert宏是在cassert头文件中定义的,所有使用assert的文件都必须包含这个头文件。

view plaincopy to clipboardprint?
assert(word.size()>threshold);
assert(word.size()>threshold);

七、函数
本章节介绍函数的定义和声明,其中讨论了如何给函数传递参数以及如何从函数返回值,然后具体分析三类特殊的函数:内联函数、类成员函数和重载函数,最后讨论"函数指针"。

1、函数必须指定返回类型,没有显式指定返回类型是不合法的:

view plaincopy to clipboardprint?
test(double v1,double v2){/*....*/} //Error:没有返回值
test(double v1,double v2){/*....*/} //Error:没有返回值

2、每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会初始化对应的形参;形参的初始化与变量的初始化一样,如果形参具有非引用类型,则复制实参的值,如果形参为引用类型,则它只是实参的别名。

3、非引用形参

(1) 指针形参

view plaincopy to clipboardprint?
#include <iostream>
using namespace std;
void reset(int *ip)
{
*ip=0;
ip=0;
}
int main()
{
int i=42;
int *p=&i;
cout<<"i="<<*p<<endl; //输出i=42
reset(p);
cout<<"i="<<i<<endl; //输出i=0
return 0;
}
#include <iostream>
using namespace std;
void reset(int *ip)
{
*ip=0;
ip=0;
}
int main()
{
int i=42;
int *p=&i;
cout<<"i="<<*p<<endl; //输出i=42
reset(p);
cout<<"i="<<i<<endl; //输出i=0
return 0;
}

为了保护指针指向的值,则形参需定义为指向const对象的指针

view plaincopy to clipboardprint?
void use_ptr(const int *p)
{
//user_ptr may read but not write to *p
}
void use_ptr(const int *p)
{
//user_ptr may read but not write to *p
}

(2) const形参:既可以给该函数传递const实参也可以传递非const的实参

复制实参并不是在任何情况下都适用,不适宜复制实参的情况包括:当需要在函数中修改实参的值时、当需要以大型对象作为实参传递时、当没有办法实现对象的复制时。

4、引用形参

(1) 使用引用形参可以返回额外的信息

(2) 利用const引用避免复制

5、main:处理命令行选项

view plaincopy to clipboardprint?
int main(int argc,char *argv[]){...}
int main(int argc,char *argv[]){...}

6、含有可变形参的函数

view plaincopy to clipboardprint?
void foo(parm_list,...);
void foo(...);
void foo(parm_list,...);
void foo(...);

7、千万不要返回局部对象的引用

view plaincopy to clipboardprint?
const string &manip(const string& s)
{
string ret=s;
return ret;//Error:不能返回局部对象的引用
}
const string &manip(const string& s)
{
string ret=s;
return ret;//Error:不能返回局部对象的引用
}

8、内联函数:可以避免函数调用的开销,内联函数应该在头文件中定义,这一点与其他函数不同。

view plaincopy to clipboardprint?
inline const string &shorterString(const string &s1,const string &s2)
{...}
inline const string &shorterString(const string &s1,const string &s2)
{...}

9、指向函数的指针:是指向函数而非指向对象的指针,如下pf声明为指向函数的指针。

view plaincopy to clipboardprint?
bool (*pf)(const string &,const string &);
bool (*pf)(const string &,const string &);

(1) 用typedef简化函数指针的定义

view plaincopy to clipboardprint?
//该定义表示cmpFcn是一种指向函数的指针类型的名字
//该指针类型为指向返回bool类型并带有两个const string引用形参的函数的指针
typedef bool (*cmpFcn)(const string &,const string &);
//该定义表示cmpFcn是一种指向函数的指针类型的名字
//该指针类型为指向返回bool类型并带有两个const string引用形参的函数的指针
typedef bool (*cmpFcn)(const string &,const string &);


(2) 指向函数指针的初始化和赋值

假设有函数如下,在引用函数名但又没有调用该函数时,函数名被自动解释为指向函数的指针。

view plaincopy to clipboardprint?
bool lengthCompare(const string &,const string &);
bool lengthCompare(const string &,const string &);

即可以使用函数名对函数指针做初始化或者赋值,如下

view plaincopy to clipboardprint?
cmpFcn pf1=0;
cmpFcn pf2=lengthCompare;
pf1=lengthCompare;
pf2=pf1;
cmpFcn pf1=0;
cmpFcn pf2=lengthCompare;
pf1=lengthCompare;
pf2=pf1;

(3) 通过指针调用函数:指向函数的指针可用于调用它所指向的函数,可以不需要使用解引用操作符,直接通过指针调用函数。

view plaincopy to clipboardprint?
cmpFcn pf=lengthCompare;
lenthCompare("hi","bye");
pf("hi","bye");
(*pf)("hi","bye");
cmpFcn pf=lengthCompare;
lenthCompare("hi","bye");
pf("hi","bye");
(*pf)("hi","bye");

八、标准IO库
C++的输入/输出由标准库提供,标准库定义了一族类型,支持对文件和控制窗口等设备的读写(IO),还定义了其他一些类型,使string对象能够像文件一样操作,从而使我们无需IO就能够实现数据与字符之间的转换。本章将介绍IO标准库的基础知识。

1、IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中的string对象。

2、IO对象不可复制或赋值

view plaincopy to clipboardprint?
ofstream out1,out2;
out1=out2;//Error:不能赋值操作
ofstream print(ofstream);
out2=print(out2);//Error:不能复制stream对象
ofstream out1,out2;
out1=out2;//Error:不能赋值操作
ofstream print(ofstream);
out2=print(out2);//Error:不能复制stream对象、

形参或返回类型也不能为流类型,如果需要传递或返回IO对象,则必须传递或返回指定该对象的指针或引用:

view plaincopy to clipboardprint?
ofstream &print(ofstream&);//OK:take a reference,no copy
while(print(out2)){...}//OK:pass reference to out2
ofstream &print(ofstream&);//OK:take a reference,no copy
while(print(out2)){...}//OK:pass reference to out2

3、条件状态:IO标准库管理一系列条件状态成员,用来标记给定的IO对象是否处于可用状态,或者碰到了哪种特定的错误。

流必须处于无错误状态,才能用于输入或输出。检测流是否可用的最简单的方法是检查其真值:view plaincopy to clipboardprint?
while(cin>>word)
//OK:read operation successful
while(cin>>word)
//OK:read operation successful

4、如果需要刷新所有输出,最好使用unitbuf操纵符,这个操作符在每次执行完写操作后都刷新流:

view plaincopy to clipboardprint?
cout<<unitbuf<<"first"<<" second"<<nounitbuf;
//等价于
cout<<"first"<<flush<<" second"<<flush;
//nounitbuf操作符将流恢复为使用正常的、由系统管理的缓冲区刷新方式
cout<<unitbuf<<"first"<<" second"<<nounitbuf;
//等价于
cout<<"first"<<flush<<" second"<<flush;
//nounitbuf操作符将流恢复为使用正常的、由系统管理的缓冲区刷新方式

5、fstream头文件定义了三种支持文件IO的类型:(1) ifstream,由istream派生而来,提供读文件的功能;(2) ofstream,由ostream派生而来,提供写文件的功能;(3) fstream,由iostream派生而来,提供读写同一个文件的功能。fstream类型除了继承下来的行为外,还定义了两个自己的新操作——open和close,以及形参为要打开的文件名的构造函数。

6、文件流对象的使用

(1) 检查文件打开是否成功

view plaincopy to clipboardprint?
ifstream infile(ifile.c_str());

if(!infile)
{
cerr<<"error:unable to open input file:"
<<ifile<<endl;
return -1;
}
ifstream infile(ifile.c_str());

if(!infile)
{
cerr<<"error:unable to open input file:"
<<ifile<<endl;
return -1;
}

(2) 将文件流与新文件重新绑定:在尝试打开新文件之前,必须先关闭当前的文件流

view plaincopy to clipboardprint?
ifstream infile("file1");
infile.close();
infile.open("file2");
ifstream infile("file1");
infile.close();
infile.open("file2");

7、文件模式:

文件模式及其含义如下表所示:

in 打开文件做读操作
out 打开文件做写操作
app 在每次写之前找到文件尾
ate 打开文件后立即将文件定位在文件尾
trunc 打开文件时清空已存在的文件流
binary 以二进制模式进行IO操作


out、trunc和app模式只能用于指定与ofstream或fstream对象关联的文件;in模式只能用于指定与ifstream或fstream对象关联的文件。所有的文件都可以用ate或binary模式打开。

8、一个打开并检查输入文件的程序:由于不清楚流in的当前状态,因此首先调用close和clear将这个流设置为有效状态,然后尝试打开给定的文件。

view plaincopy to clipboardprint?
ifstream& open_file(ifstream &in,const string &file)
{
in.close();
in.clear();
in.open(file.c_str());
return in;
}
ifstream& open_file(ifstream &in,const string &file)
{
in.close();
in.clear();
in.open(file.c_str());
return in;
}

9、字符串流

(1) istringstream,由istream派生而来,提供读string的功能

(2) ostringstream,由ostream派生而来,提供写string的功能

(3) stringstream,由iostream派生而来,提供读写string的功能

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/rocket5725/archive/2009/09/18/4566753.aspx

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics