有很长时间没用C++了,现在重新拾起来,做点笔记
1 STL(模板库)
STL是Standard TemplateLibrary的简称,中文名标准模板库,惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。STL现在是C++的一部分,因此不用安装额外的库文件。
2 i++和++i的区别
i++ :先引用后增加
++i :先增加后引用
i++ :先在i所在的表达式中使用i的当前值,后让i加1
++i :让i先加1,然后在i所在的表达式中使用i的新值
++是i先不自加,在语句完后自加,++i先自加;列如a=1+i++;i本来为1的话,这里a=1+1;语句完后i才加1为2;
3 c++ to_String()
函数原型:
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
功能:
将数值转化为字符串。返回对应的字符串。
4 fabs:函数简介
类似的还有:
float fabsf(float num);
double fabs(double num);
long double fabsl(long double num);
fabsf() and fabsl()都是在C99中增加的!
用法:#include <math.h>
功能:求浮点数x的绝对值
说明:计算|x|, 当x不为负时返回x,否则返回-x
类似函数:abs
5 <algorithm>是c++特有的STL模板的算法头文件 包含了一些特定的算法函数
包括sort(),stable_sort(),partical_sort(),nth_element()等常用的算法函数
6 头文件<cstdio>(stdio.h)
执行输入/输出操作的C++库
输入与输出操作在C++中也可以通过使用C标准输入输出库(cstdio,在C语言中为stdio.h)实现。该库使用所谓的“流“操作物理设备,如键盘、打印机、终端或系统支持的其它类型文件。流是与这些物理设备以统一方式交互的抽象概念。所有的流都具有独立于它们相关联的物理设备个体特性的相似属性。
流在cstdio库中以指向FILE对象的指向方式操作。一个指向FILE对象的指针唯一表示一个流,并且在设计该流的操作中作为参数使用。
存在三种标准流:stdin、stdout与stderr,它们自动为所有使用该库的程序公开创建。
7 typedef的语法描述
在现实生活中,信息的概念可能是长度,数量和面积等。在C语言中,信息被抽象为int、float和 double等基本数据类型。从基本数据类型名称上,不能够看出其所代表的物理属性,并且int、float和double为系统关键字,不可以修改。为了解决用户自定义数据类型名称的需求,C语言中引入类型重定义语句typedef,可以为数据类型定义新的类型名称,从而丰富数据类型所包含的属性信息。
typedef 类型名称 类型标识符;
typedef为系统保留字,“类型名称”为已知数据类型名称,包括基本数据类型和用户自定义数据类型,“类型标识符”为新的类型名称。例如:
typedef double LENGTH;
typedef unsigned int COUNT;
定义新的类型名称之后,可像基本数据类型那样定义变量。例如:
typedef unsigned int COUNT;
8 C语言中的&是取变量逻辑地址的操作, 与变量本身所在的物理地址没有关系,它直接与变量的值相关,即使变量本身所在的物理地址改变,对&操作也没有影响,&操作取值不会改变.
而*是取变量物理地址的操作, 即使变量本身所在的逻辑地址改变,对&操作也没有影响, &操作取值不会改变.但是一旦物理地址中的数据改变,*操作所得的数据也将随之改变.
这就像是在一栋楼房中找人,&是按入住人的名字找人,而*是按门牌号找人, 虽然同是找人,但还是有本质上的区别的.当且仅当门牌号对应的人与按入住人姓名找的人相同的时候, 找到的人才是同一个人.
&的用法和含义,见下面的例子:
main()
{ int i=3,j=5;
change(i,j);
printf("i1=%d ,%d",i,j);
}
void change(int n, int m)
{ n=n+m;
printf("n=%d,m= %d ",n,m);
}
运行的结果为:
i1=3,5
n=8, m=5
现把上面的程序改为:
main()
{ int i=3,j=5;
change(&i,j);
printf("i1=%d ,%d",i,j);
}
void change(int &n, int m)
{ n=n+m;
printf("n=%d,m= %d ",n,m);
}
运行的结果为:
i1=8,5
n=8, m=5
为什么会产生这样的结果?
C语言中的&是取变量地址的操作,在执行main(){int i=3,j=5; 时,操作系统(os)会对变量i,j分配内存单元,如i的地址是2800,os只管理2800的单元,它并不知变量i,执行i=3;则2800单元中的内容是3,用符号(2800)=3表示,执行调change函数,把i的地址2800传递给n,&n=2800,在执行n+m,则2800单元中的内容变成8,(2800)=8,再退回到main时,执行 printf("i1=%d ,%d ",i,j);则应该把2800单元中的内容输出(注意在os中没有变量的处理,只有对地址的管理),这时2800单元中的内容已变成8,所以输出是i1=8,5。我们注意到此时i和n实际上是共用的同一个地址,所以n的改变会影响上一级的模块中的i变量,即参数的双向传递!
实际中由于c语言并不是一种非常严谨的语言,它本身并不提供参数的双向传递功能,是用地址来实现的。在数据结构的课程中,以后只要发现参数中有&符号,它就是双向传递,即既有输入又有输出,可以把它理解成全局量,但全局量在整个系统的所有模块都起作用,&只在定义的函数(模块)中起作用,可以理解为“局部的全局量”。
&符号我想不出有很好和严谨的描述方法,如果一定要与某些东西类比,在pascal中的VAR是最接近的,如Proc change(VAR n:integer, m:integer)
9 这里主要是讨论fstream的内容:
1. #include <fstream>
2. ofstream //文件写操作 内存写入存储设备
3. ifstream //文件读操作,存储设备读区到内存中
4. fstream //读写操作,对打开的文件可进行读写操作
10 DBL_EPSILON和 FLT_EPSILON主要用于单精度和双精度的比较当中:
1. double a = 0.5;
2. if (a == 0.5) //正确
3. x++;
4.
5. double b = sin(M_PI / 6.0);
6. if (b == 0.5) //错误
7. x++;
第一个比较正确,第二个可能正确也可能错误,b==0.5的结果取决于处理器、编译器的版本和设置。比如 Visual C++ 2010 编译器编译后运行b的值为0.49999999999999994
一种正确的比较方法应该是这样的:
double b = sin(M_PI / 6.0);
1. if (fabs(b - 0.5) < DBL_EPSILON)
2. x++;
以上的例子可以看出,EPSILON是最小误差。 是EPSILON+X不等于X的最小的正数。
11 函数名: getchar
功能:从stdio流中读字符
用法: int getchar(void);
getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdio流中每次读入一个字符.getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕.如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取.也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键.
12 C++注释规范
1 源文件头部注释
列出:版权、作者、编写日期和描述。
/*************************************************
Copyright:bupt
Author:
Date:2010-08-25
Description:描述主要实现的功能
**************************************************/
每行不要超过80个字符的宽度。
2 函数头部注释
/*************************************************
Function: // 函数名称
Description: // 函数功能、性能等的描述
Calls: // 被本函数调用的函数清单
Table Accessed: // 被访问的表(此项仅对于牵扯到数据库操作的程序)
Table Updated: // 被修改的表(此项仅对于牵扯到数据库操作的程序)
Input: // 输入参数说明,包括每个参数的作
// 用、取值说明及参数间关系。
Output: // 对输出参数的说明。
Return: // 函数返回值的说明
Others: // 其它说明
*************************************************/
3 数据结构声明的注释(包括数组、结构、类、枚举等)
如果其命名不是充分自注释的,必须加以注释。对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域的注释放在此域的右方。
/* sccp interface with sccp userprimitive message name */
enum SCCP_USER_PRIMITIVE
{
N_UNITDATA_IND, /* sccp notify sccp user unit data come */
N_NOTICE_IND, /* sccp notifyuser the No.7 network can not */
/* transmission thismessage */
N_UNITDATA_REQ, /* sccp user's unit data transmission request*/
};
13 输入输出流:
C语言
1. printf("%d",f); //f为单精度变量,输出变量中前两个字节的内容
2. printf("%d","C++");//输出字符串"C++”的起始地址
1. scanf("%d",&i); //正确,输入一个整数,赋给整型变量i
2. scanf("%d",i); //漏写&
C++
iostream 包含了对(标准)输入输出流进行操作所需的基本信息。
fstream 用于用户管理的文件的I/0操作。
sbsbeam 用于字符串流I/0。
stdiostream 用于混合使用C和C++的I/0机制时,例如想将C程序转变为C++程序。
iomamp 在使用格式化I/0时应包含此头文件。 格式输出
1. #include <iostream>
2. #include<string>
3. #include <iomanip> //不要忘记包含此头文件
4. using namespace std;
5. int main()
6. {
7. int a;
8. cout<<"input a:";
9. cin>>a;
10. cout<<"dec:"<<dec<<a<<endl; //以上进制形式输出整数
11. cout<<"hex:"<<hex<<a<<endl; //以十六进制形式输出整数a
12. cout<<"oct:"<<setbase(8)<<a<<endl;//以八进制形式输出整数a
13. string pt= "China"; //pt指向字符串”China”
14. cout<<setw(10)<<pt<<endl; //指定域宽为10,输出字符串
15. cout<<setfill('*')<<setw(10)<<pt<<endl;//指定域宽10,输出字符串,空白处以“*”填充
16. double pi=22.0/7.0; //计算pi值
17. cout<<setiosflags(ios::scientific)<<setprecision(8);//按指数形式输出,8位小数
18. cout<<"pi="<<pi<<endl; //输出pi值
19. cout<<"pi="<<setprecision(4)<<pi<<endl;//改为4位小数
20. cout<<"pi="<<setiosflags(ios::fixed)<<pi<<endl;//改为小数形式输出,精度为4
21. cout<<"pi="<<fixed<<pi<<endl;//fixed确定小数点后精度为4
22. return 0;
23. }
在头文件iostream.h中定义了cin,cout,cerr,clog4个流对象,cin输人流,cout,cerr,clog是输出流。
(1)不带参数的get函数
其调用形式为: cin.get() //用来从指定的输人流中提取一个字符(包括空白字符)函数的返回值就是读入的字符。
(2)有一个参数的get函数
其调用形式为:
cin.get(ch)// 其作用是从输人流中读取一个字符,赋给字符变量ch。
(3)有3个参数的get函数
其调用形式为
cin.get(字符数组,字符个数n,终止字符)
或
cin.get(字符指针,字符个数n,终止字符)
其作用是从输入流中读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组),如果在读取n-1个字符之前遇到指定的终止字符,则提前结束读取。如果读取成功则函数返回非0值(真),如失败(遇文件结束符)则函数返回0值(假)。
(4) getline函数的作用是从输人流中读取一行字符,其用法与带3个参数的get函数类似。
即: cin.getline(字符数组(或字符指针),字符个数n,终止标志字符)
stringstr;
while(getline(cin, str)){
} //整行输入
15 文件读写:
1. #include <fstream>
2. ofstream //文件写操作 内存写入存储设备
3. ifstream //文件读操作,存储设备读区到内存中
4. fstream //读写操作,对打开的文件可进行读写操作
1.打开文件
在fstream类中,成员函数open()实现打开文件的操作,从而将数据流和文件进行关联,通过ofstream,ifstream,fstream对象进行对文件的读写操作
函数:open()
打开文件的方式在ios类(所以流式I/O的基类)中定义,有如下几种方式:
ios::in | 为输入(读)而打开文件 |
ios::out | 为输出(写)而打开文件 |
ios::ate | 初始位置:文件尾 |
ios::app | 所有输出附加在文件末尾 |
ios::trunc | 如果文件已存在则先删除该文件 |
ios::binary | 二进制方式 |
这些方式是能够进行组合使用的,以“或”运算(“|”)的方式:例如
1. ofstream out;
2. out.open("Hello.txt", ios::in|ios::out|ios::binary)
当文件读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。成员函数close(),它负责将缓存中的数据排放出来并关闭文件。这个函数一旦被调用,原先的流对象就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程所访问了。为防止流对象被销毁时还联系着打开的文件,析构函数将会自动调用关闭函数close。
1. // writing on a text file
2. #include <fiostream.h>
3. int main () {
4. ofstream out("out.txt");
5. if (out.is_open())
6. {
7. out << "This is a line.\n";
8. out << "This is another line.\n";
9. out.close();
10. }
11. return 0;
12. #include <iostream.h>
13. #include <fstream.h>
14. #include <stdlib.h>
15.
16. int main () {
17. char buffer[256];
18. ifstream in("test.txt");
19. if (! in.is_open())
20. { cout << "Error opening file"; exit (1); }
21. while (!in.eof() )
22. {
23. in.getline (buffer,100);
24. cout << buffer << endl;
25. }
26. return 0;
27. }
16 错误处理error C4996: 'fopen': This function or variable maybe unsafe
(1)点击项目--》属性--》c/c++--》预处理器--》预处理定义--》点击下拉按钮
(2)添加_CRT_SECURE_NO_WARNINGS,点击确定就ok了。
17 vector 的用法
1.构造函数
· vector():创建一个空vector
· vector(int nSize):创建一个vector,元素个数为nSize
· vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
· vector(const vector&):复制构造函数
· vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector中
2.增加函数
· void push_back(const T& x):向量尾部增加一个元素X
· iterator insert(iterator it,const T&x):向量中迭代器指向元素前增加一个元素x
· iterator insert(iterator it,int n,constT& x):向量中迭代器指向元素前增加n个相同的元素x
· iterator insert(iterator it,const_iteratorfirst,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据
3.删除函数
· iterator erase(iterator it):删除向量中迭代器指向元素
· iterator erase(iterator first,iteratorlast):删除向量中[first,last)中元素
· void pop_back():删除向量中最后一个元素
· void clear():清空向量中所有元素
4.遍历函数
reference at(int pos):返回pos位置元素的引用
· reference front():返回首元素的引用
· reference back():返回尾元素的引用
· iterator begin():返回向量头指针,指向第一个元素
· iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
· reverse_iterator rbegin():反向迭代器,指向最后一个元素
· reverse_iterator rend():反向迭代器,指向第一个元素之前的位置
5.判断函数
· bool empty() const:判断向量是否为空,若为空,则向量中无元素
6.大小函数
· int size() const:返回向量中元素的个数
· int capacity() const:返回当前向量张红所能容纳的最大元素值
· int max_size() const:返回最大可允许的vector元素数量值
18 static void 定义的函数
有些函数声明为 static void ,目的是
不会出现在编译成obj文件的符号表中. obj之外的程序就无法链接到这个obj文件的函数。
也就是其它文件链接此obj文件时是无法使用此函数的。
static 是说这个函数只在本文件可见。这样避免不同文件写了一个名字的函数出事。
static 表示该函数只在本文件内可见;与之相反的是extern,此函数只能在本编译单元(.c)内查找,不能调用其它编译单元的定义体。
static修饰是给编译器看的,告诉编译器,本函数在编译成的obj里是不可见的,这样,在别的函数里使用的话,是连接不到的,这样就保证了此函数只在本文件中可用。也有例外,就是其他文件直接把他include进来。
19 static_cast< type-id > ( expression )
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性
20 int A[ ] = {1, 8, 9};
Sizeof A /sizeof(int) 可以得到数A 的长度
21 在C, C++中不存在UINT这个关键字,UINT类型是unsigned int派生出来的。int是带符号的,表示范围是:-21474 83647 到 21474 83648。uint是不带符号整形,表示范围是0到42949 67295(2^32-1),即第一个数字不表示符号。
22 stack<char> s;这是参数化模板,声明存放char类型的stack容器
23 长整形
int 是 C 语言的基本整数类型,可以满足我们处理一般数据的需求。C 语言还提供了四个可以修饰 int 的关键字:short、long、signed,以及 unsigned。利用这四个关键字,C 语言标准定义了以下整数类型:
1)short int(可简写为 short),和 int 一样,也是有符号整数
2)long int(简写:long),有符号整数
3)long long int(简写:long long),C99 标准添加的类型,
有符号整数
4)unsigned int(简写:unsigned),无符号整数,不能表示负数
5)unsigned long int(简写:unsigned long),无符号整数,
不能表示负数
6) unsignedshort int(简写:unsigned short),无符号整数,
不能表示负数
7)unsigned long long int(简写:unsigned long long),
int型:32位整型,取值范围为-2^31 ~ (2^31 - 1) .
long:在32位系统是32位整型,取值范围为-2^31 ~ (2^31 - 1);在64位系统是64位整型,取值范围为-2^63 ~ (2^63 - 1)
longlong:是64位的整型,取值范围为-2^63 ~ (2^63 - 1)。
24 abs() 与fabs() 的区别
abs()主要用于对求整数的绝对值,在“stdlib.h”(或 <cstdlib>)头文件里面。
而fabs( )主要是求精度要求更高的double ,float 型的绝对值,在<cmath>头文件里。两者在只#include<cmath>时都可以使用。
25 ^=是C/C++的一个符合运算符。表示异或赋值。
如:
a^=b相当于:a=a^b;
异或就是两个数的二进制形式,按位对比,相同取0,不同取一
26 这是c++11的新特性,范围for,相当于java的for each。v是一个可遍历的容器或流,比如vector类型,i就用来在遍历过程中获得容器里的每一个元素。
例如:vector<int> v={1,2,3,4};
for(autoi:v)
cout<<i;
结果就是1234
27 cin>>hex>>a; 以十六进制的格式输入a
hex 是16进制,oct是8进制,dec是10进制,你输入3个都是12.
16进制12转成10进制是18,8进制12转成10进制是10,10进制12转成10进制是12.
其实cin是一个对象,而>>是重载的操作符,你可以把>>理解为函数即cin.>>(hex),把hex作为参数。这样cin这个对象就设置里面的成员变量的值,让它接收输入时能按16进制输入,即把输入的12当成16进制的12.执行完后会返回cin的引用,知道引用吧,从反汇编看它是返回一个指针值,
就是指向cin自己,这样当再次用>>时又能调用cin.>>(a)连续用>>调用,能获得连续输入。
这次调用就是接收输入了。同样的道理,后面的也是这样。
28
C++ isalpha、islower、isupper、isalnum、isblank、isspace函数
必须添加<cctype>头文件
isalpha字母(包括大写、小写)islower(小写字母)isupper(大写字母)isalnum(字母大写小写+数字)isblank(space和\t)isspace(space、\t、\r、\n)
29. 为了便于阅读,可以将较长的语句拆分成两行甚至多行,除了最后一行之外,在每一个分行后面加一个反斜杠“\”,这样编译的时候,系统会自动将这几个分行读成一个语句处理。比如:
1) 用在宏定义中:
#defineCV_ARE_SIZES_EQ(mat1, mat2) \
((mat1)->rows == (mat2)->rows&& (mat1)->cols == (mat2)->cols)
2) 用在printf中,有时候printf中语句太长,需要切分,则需用到反斜杠;
3) 用“//”只能注释当前行的语句,想要将下一行一起注释掉,则可以在该行最后加上反斜杠。
另外,反斜杠除了强制换行的作用之外,还有转义符的意思。如:“\n”表示换行符,"\t" "\b"等,此时反斜杠表示转义,执行反斜杠后面的符号表示的意思。
但若要取反斜杠的本意,则需要在反斜杠之前再加一个反斜杠才能正确表示。比如我要在程序中读取F:\OpenCV2.0\vs2008\videos\videos1.avi,,我不能直接将这样表示,而应该在每一个反斜杠前面再加一个反斜杠,表示为:F:\\OpenCV2.0\\vs2008\\videos\\videos1.avi,这样才能正确读取你要的文件。
总结一下,目前个人了解的反斜杠的作用是两种:
1 是作为转义字符,将进行的操作是紧跟其后的字符的操作。
2 与回车键组合进行强制换行。在要强制换行的地方输入反斜杠然后回车,系统编译的时候会自动将反斜杠下面的一行与前面的一行解释成一个语句。
30. C++中##的意思
它是个用在宏中的关键字.
表示将前后数据连接起来.
如: #define Conn(str) str##MyName
这样使用 Conn(123)
则等价于 123MyName
其他待续。。。