:
endl;
endl是一个特殊值,称为操作符(manipulator),将它写入输出流时,具有输出换行的效果,并刷新与设备相关联的缓冲区(buffer);忘记刷新输出流可能会造成输出停留在缓冲区中,如果程序崩溃,会导致对程序崩溃位置的错误推断。
3.C++程序中大部分出现的空格符的地方可以用换行符代替。
两个例外是:
1、字符串字面值中的空格符不能用换行符代替2、空格符不允许出现在预处理指示中
4.定义变量时,应该给变量赋初始值
5.太多的注释混入代码可能会使代码难以理解,通常最好是把一个注释块放在所注释的代码的上方
6.自定义头文件用双引号(“”)把头文件括起来(通常在源文件所在路径),标准库的头文件用<>括起来(在系统路径环境中查找)
7.8位块一个字节,32位块四个字节作为一个字
8.超出取值范围的赋值将会被采取取模操作
9.0开头的字面值整数表示八进制,0x开头的整数表示十六进制
10.定义长整形的时候,应该使用大写字母L,表示扩展精度,避免小写的l与1混淆
123u/*unsigned*/
123L/*long*/
11.'a'之前加上L,可以得到wchar_t类型的宽字符字面值L'a'
12.在一行末尾加'\'可以将此行与下行作同一行处理,但是后面不能加注释或空格
13.命名习惯最重要的是保持一致
14.复制初始化intival=1024;
直接初始化intival(1024);//更加灵活且效率更高
初始化不是赋值,赋值是擦除原来的数值
15.计数器初始化string变量
std:
:
stringall_nines(10,'9');
得到的值是9999999999
16.const变量定义后就不能修改,所以必须初始化
17.externconstintbufsize=1024
对const变量指定extern可以让整个程序中访问const对象
18.引用——对象的另一个名字
intival=1024;
int&refval=ival;//对引用对象复制必须用与该引用同类型的对象初始化,而且必须在定义引用对象的时候对其初始化赋值
可以读取但不能修改引用的对象
19.枚举类型
enumopen_modes{input,output,append=1,another};
第一个枚举成员赋值为0,第二个是1,第三个是1,第四个是2
20.类定义后面要加分号
21.默认情况下struct成员为public,class成员是private
22.预处理可以防止头文件被反复引用
#ifndefSALESITME_H
#defineSALESITME_H
#endif
23.使用命名空间
usingstd:
:
cin;
usingstd:
:
cout;
usingstd:
:
string;
24.任何储存string的size操作结果的变量必须是string:
:
size_type类型,不要把size的返回值赋值给int变量
for(string:
:
size_typeindex=0;index!
=s.size();++index)
25.任何一个大写字母都小于任何一个小写字母
26.对字符串进行混合连接操作时,+操作符的作用操作数必须至少有一个是string类型的
错误的连接:
strings1="hello"+",";
strings2="hello"+"11"+s1;
27.C标准库的文件命名name.h形式在C++中为cname.h
28.C++程序员优先选用!
=而不是<来编写循环判断条件
29.vector可以使用下标操作,但是下标必须是已经初始化的元素才
错误的尝试使用下标对vector进行添加操作方法:
vectorivec;
for(vector:
:
size_typeix=0;ix!
=10;++ix)
ivec[ix]=ix;//错误,ivec没有元素初始化
vector的添加元素
for(vector:
:
size_typeix=0;ix!
=10;++ix)
ivec.push_back(ix);
30.所有的标准库容器都定义了相应的迭代器类型,只有少数容器支持下标操作
vector:
:
iteratoriter;
31.每种容器定义都定义了一对命名为begin和end的函数
32.迭代器使用示例:
for(vector:
:
iteratoriter=iver.begin();iter!
=ivec.end();++iter)//end操作返回的迭代器不指向vector中任何实际元素
*iter=0;//解引用操作符*,访问迭代器指向的元素
33.声明一个const迭代器的时候,必须初始化迭代器
34.二进制位集处理标准库bitset,在定义bitset时要明确bitset含有多少位
bitset<32>bitvec;
长度值必须是整型值常量或者是已用常量值初始化的整形的const对象
35.用string对象初始化bitset对象时,string对象直接表示为位模式。
从string对象读入位集的顺序是从右到左
stringstrval("1100");
bitset<32>bitvec4(strval);
bitvec4位模式中第2和第3的位置为1,第0和第1位置为0。
string和bitset对象之间是反向转化的
36.数组一经创建,就不允许添加新的元素。
指针则可以像迭代器一样用于遍历和检查数组中的元素
37.C++应尽量使用vector和迭代器类型,而避免使用低级的数组和指针
38.非const变量和要到运行阶段才能知道其值的const变量都不能用于定义数组的维数
constunsignedsz=get_size();
39.charca[]={'C','+','+','\0'};
使用一组数组字面值初始化字符数组时,要注意添加结束字符串的空字符
constcharca[6]="Daniel";//错误,应该7个字符元素,一个用于存放空字符null
40.vector使用vector:
:
size_type作为下标的类型,而数组下标类型是size_t
41.指针的两种定义方法
string*p;
string*p;
42.string*p1,p2;//只有p1是指针,p2是string对象
43.void*指针可以保存任何类型对象的地址
44.在表达式中使用数组名时,该名字会自动转换为指向数组第一个元素的指针
45.C++强制要求指向const对象的指针也必须具有const特性
constdouble*cptr;
46.使用标准库函数strncat和strncpy比strcat和strcpy函数更安全
47.在复制和串联字符串时,要注意算上结束符null
48.标准库函数strlen返回的是字符串的长度,并不包括字符串结束符,在获得字符串长度上必须加1以便知动态分配时预留结束符的存储空间
49.在要求C风格字符串的地方不可直接使用标准库string类型对象
char*str=st2.c_str();
50.一元操作符的优先级最高
51.strings("ExpressionsinC++arecomposed...");
string:
:
iteratorit=s.begin();
while(it!
=s.end()&&!
isspace(*it)){
*it=toupper(*it);
++it;
}
52.if(i该条件将k和0或者1比较
53.位操作符最好使用unsigned整型操作数
54.移位操作的右操作数必须是正数而且必须严格小于左操作数位数的值
55.位异或,两个位之间不同,则为1,相同为0
56.移位操作符比关系操作符、赋值操作符、条件操作符高
cout<<(10<42);
57.只有在必要的时候才使用后置操作符
58.点操作符,用于获取类类型对象的成员
item1.same_isbn(item2);
59.sizeof操作符返回值类型为size_t
60.double向int转换自动按截尾形式进行
61.while(cin>>s)
这里隐式使用了IO标准库定义的类型转换
62.强制将dval类型转换成int类型
ival*=static_cast(dval);
63.空语句常见于循环条件判断阶段就能完成全部循环工作的情况
使用是最好加上注释,以便使任何读这段代码的人都知道该语句是有意省略的
64.在while或者if条件后面额外添加分号,往往会彻底改变程序员的意图
65.block(块)标识了一个作用域
66.if和else匹配时,可以使用花括号指定匹配
67.switch语句中两个case具有相同的数值,会导致编译错误
68.for语句的init-statement中可以定义多个对象,但只能出现一个语句,而且必须具有相同的类型
69.break只能出现在swich语句中
70.stringinbuf;
while(cin>>inbuf&&!
inbuf.empty()){
if(inbuf[0]!
='_')
continue;
}//只有下划线开头的单词才做处理
71.使用NDEBUG预处理变量实现有条件调试代码
intmain()
{
#ifndefNDEBUG
ceer<<"startingmain"<#endif
}
NDEBUG定义了,自动跳过
72.if(word.size()cerr<<"Error"<<__FILE__//文件名
<<":
line"<<__LINE__<<<"compiledon"<<__DATE__//文件被编译的日期
<<"at"<<__TIME__<73.voidfcn(constinti){}
voidfcn(inti){}
发生错误,在C语言中,具有const形参或非const形参的函数并无区别
74.将实参定义为引用类型
voidswap(int&v1,int&v2)
{
inttmp=v2;
v2=v1;
v1=tmp;
}
参数值在函数内产生的修改可以被传到函数外
75.非const引用形参只能与完全同类型的非const对象关联
76.应该将不需要修改的引用形参定义为const引用
.编译器检查数组形参关联的实参时,只会检查实参是不是指针、指针类型和数组类型是否匹配,不会检查数组长度
77.f(int&arr[10])
f(int(&arr)[10])
&arr两边的括号是必须的,因为下表操作符具有更高的优先级
78.多维数组编译时编译器忽略第一维的长度
79.确保函数的操作不超过数组实参的边界的方法:
1:
数组本身放置一个标记来检测数组的结束。
C语言
2:
传递指向数组第一个和最后一个元素的下一个位置的指针。
3:
将第二个形参定义为数组的大小
80.只允许主函数main没有返回值就结束
81.在含有return语句的循环后没有提供return语句是很危险的
82.千万不要返回局部对象的引用
函数执行完毕是,将释放分配给局部对象的存储空间,此时对局部对象的引用将会指向不确定内存
83.一个函数只能定义一次,但可以声明多次
84.主函数不能调用自身
85.如果提供了实参,将覆盖默认的实参值
sringscr(string:
:
size_typeheight=24,string:
:
size_typewidth=80,charbackground='');
stringscreen;
screen=scr();//默认实参2480''
screen=scr(66);//60默认实参80''
screen=scr(66,256);//66256默认实参''
screen=scr(66,256,'#');//66256'#'
尽量使最少使用默认实参的形参排在最前,最可能使用默认实参的形参排最后
86.形参也是自动对象,只有在函数被调用的时候才会存在的对象是自动对象
87.static对象一旦被创建,在程序结束前都不会被撤销
88.使用内联函数
inlineconststringshorterString(conststring&s1,conststring&s2)
{
retuens1.size()s1:
s2;
}
cout<相当于
cout<<(s1.size()s1:
s2)<89.内联函数应该在头文件中定义,不同于其他函数
90.构造函数与类同名,而且没有返回类型
在创建类类型对象时使用的初始化式
91.在类定义外面定义的成员函数必须指明它们是类的成员
92.函数不能仅仅基于返回类型来实现重载
93.C++中的引用变量、默认实参和函数重载
引用变量讲得通俗一点就是变量的别名。
inta=2;int&b=a;
默认实参是指当函数调用中省略了实参时自动使用的一个值。
94.排列形参时,把最少使用默认实参的形参放在最前,最可能使用默认实参的形参排在最后
95.默认实参只能指定一次
96.使用重载对程序未必是件好事
97.函数的声明要放在头文件中
98.含有多个形参的重载确定,程序选择匹配最佳的函数
99.仅仅当形参是引用或指针时,形参是否为const才有影响
100.不能仅仅基于指针是否为const来实现函数的重载
f(int*)
f(int*const);//错误
101.指向函数的指针
bool*bf(conststring&,conststring&);
102.使用typedef简化函数指针的定义
typedefbool(*comFcn)(conststring&,conststring&);
boollengthCompare(conststring&,conststring&);
comFcnpf1=0;
comFcnpf2=lengthCompare;
只能使用同类型的函数或函数指针或0值常量表达式进行初始化或赋值
103.函数的形参指向函数指针的两种编写方式
voiduseBigger(conststring&,conststring&,bool(conststring&,conststring&));
voiduseBigger(conststring&,conststring&,bool(*)(conststring&,conststring&));
104.IO类型的头文件中定义:
iostream定义读写控制窗口的类型fstream定义读写已命名文件的类型sstream定义储存在内存中的string对象
105.对stream类型添加国际字符支持者原类型前加cwchar_t,wifstram,wofstream,wfstream
对应的标准输入对象wcin,标准输出wcout,标准错误wcerr
106.标准库类型(IO,ofstream,instream)不允许做复制或赋值操作
只有支持复制的元素类型才能储存在vector或者其他容器类型中,所有流对象不能存储在vector或其他容器中
返回值也不能为流类型
107.检测是否可用的最简单方法就是检查其是否为真值
If(cin)
While(cin>>word)
108.IO的条件状态bad,fail,eof,good操作提示
109.流状态的查询和控制
intival;
While(cin>>ival,!
cin.eof())//直到读到文件结束符为止,注意这里while有两个参数
{
If(cin.bad())//检查流是否已经被破坏
Throw.runtime_error("IOstreamcorrupted!
");
If(cin.fail())//如果输入无效,输出警告并且清除failbit状态
{
Cerr<<"baddata,tryagain";
Cin.clear(istream:
:
failbit);
Continue;
}
}
110.多种状态管理
Is.setstate(ifstream:
:
badbit|ifstream:
:
failbit);
111.输出缓冲区的刷新的方法
Cout<<"hi!
"<Cout<<"hi!
"<Cout<<"hi!
"<112.Unitbuf操作符刷新所有输出,在每次执行完写操作后都刷新流
Cout<相当于cout<<"first"<113.如果仅仅因为缓冲区没有刷新,很容易浪费很多时间进行调试,所以要经常使用endl而非'\n'
114.使用c_str成员获取C风格字符串,调用open或使用文件名作为初始化式时,需要传递的实参为C风格字符串,比较好的方法是把文件名读入string对象
Ifstreaminput;
Vector:
:
const_iteratorit=files.begin();
While(it!
=file.end())
Input.open(it->c_str())//打开文件,注意这里要打开为string对象,用c_str()成员
{
If(!
input)
Break;
While(input>>s)
Process(s);
Input.close();
Input.clear();
++it;
}
115.重新捆绑文件时,必须先关闭现在的文件
Ifstreaminfile("in");//打开文件名为in的文件读取
Infile.close();//必须先关闭后再读取第二个文件
Infile.open("next");//打开文件名为next的文件读取
116.如果需要重用文件流读写多个文件,需要在读另一个文件前调用clear清除该流的状态
117.顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定
118.顺序容器类型:
vector(支持快速随机访问)list(支持快速插入删除)deque(双端队列)
顺序容器适配器stack(后进先出)queue(先进先出)priority_queue(有优先级管理的队列)
119.使用顺序容器需要使用的头文件
#include
#include
#include
120.容器的声明方法容器类型加容器中元素类型vectorsvec;
Listilist;
121.将一个容器复制给另一个容器时,类型必须匹配,容器类型和元素类型都必须相同
但使用迭代器的时候,不要求容器类型相同,元素类型也可以不相同,只要他们相互兼容
122.初始化指定数目的元素
Constlist:
:
size_typelist_size=64;
Listslist(list_size,"eh?
");//list容器中初始化为64个"eh?
"的字符串
接受容器大小做形参的构造函数只适用于顺序容器
123.容器元素类型的约束:
1必须支持赋值运(引用不支持一般意义上的赋值运算)2元素类型的对象必须支持复制(IO库类型不支持赋值或复制运算)
124.外加的数据类型需要提供大小并提供单个初始化式的构造函数,假设Foo类型没有构造函数,但提供了一个int类型形参的构造函数
Vectorempty;//声明成功,不指定容器大小和容器内元素
Vectorbad(10);//没有构造函数不能仅指定容器大小进行声明
Vectorok(10,1);//由于有int形参的构造函数,所以声明成功
125.必须用空格隔开相邻的>符号,否则会被系统认为是>>操作符
Vector>lines;
Vector>lines;//错误系统认为是位操作符
126.只有vector和deque容器提供迭代器算术运算和用==和!
=以外的关系操作符比较容器
关系操作符仅仅适合vector和deque容器这两种容器都支持元素位置的随机访问,因此可以有效实现算术和关系运算
Vector:
:
iteratoriter=vec.begin()+vec.size()/2;//取中值
127.begin()返回迭代器的第一个元素,End()迭代器指向的是最后一个元素的下一个位置元素表示范围为[first,last)
128.first和last不相等的时候迭代器范围内至少有一个元素,相等时,迭代器为空
rbegin()返回一个逆序迭代器,指向最后一个元素,rend()返回一个逆序迭代器,指向第一个元素前面的位置
129.所有容器都支持c.push_back(t)操作,在容器尾部插入一个元素,c.push_front(t)只适用于list和deque容器,在前段添加元素,c.insert(p,t)适用于p前插入值为t的新元素,c.insert(p,t)在p指向的元素前插入值为t的新元素,c.insert(p,n,t)在p指向的元素前插入n个值为t的元素,p指向的元素钱插入迭代器b和e标记的范围内的元素
130.使用一段新元素初始化容器时,新容器存放的是原始元素的副本
131.不要存储end操作返回的迭代器,添加或删除deque或vector容器内的元素都会导致存储的迭代器失效
132.容器的比较,如果两个容器都不是对方的子列,比较的结果取决于所比较的第一个不相等的元素
133.C++语言只允许两个容器做元素类型定义的关系运算
134.容器大小操作c.size()返回容器内元素个数,c.max_size()返回容器容量,c.empty()判断容器是否为空,c.resize(n)增加容器n个大小
135,c.front()和c.back()返回第一个和最后一个成员,c[n]/c.at[n]返回下标为n的元