C/C++基础

C/C++基础

转自:http://blog.csdn.net/fangbaolei2088/article/details/7990519

1.编译器g++
g++ -c 只编译不连接,生成.o文件
g++ -o 修改编译后生成的文件的名字(默认为a.out)


2.C++优点
Supporting data abstraction
Object-oriented
Contains all C features
Portable and efficient as C
Can be linked to existing C libraries and functions(!!)
...


3.变量名
第一个字母必须是字母或下划线
只能使用字母或下划线或数字
中间不能有空格
不能是保留字,不能与库函数重名
区分大小写

 


4.基本数据类型
char=> unsigned/signed char
int=> unsigned/signed long/short int
float=> double, long double
bool

 


5.四个类型转换算子(详细见后面)
static_cast: 
const_cast:
reinterpret_cast:
dynamic_cast:


6.运算符
优先级前三名:() .或-> 单目
优先级后三名: ?: = 逗号


7.枚举类型
enum color{RED, BLUE=10, GREEN}; // 默认数值为0, 1, 2...这样改变值后为0, 10, 11...
color c = GREEN;


8.表达式(略)


9.控制语句
if(){}else{}
while(){}
do{}while();
for(){}
switch(){case;}


10.函数
函数三要素:返回类型、函数名、参数表
声明(无函数体;参数表参数可无参数名,但必须有类型)
定义(有函数体{})
调用函数实际是利用栈操作,执行完一个函数时候,栈释放
使用默认参数(必须从右至左指定默认值)


11.内联函数(inline)
编译时,只是将内联函数的代码粘贴到调用处,不进行栈操作,所以速度快
必须声明与定义放一起
不支持控制语句(所以实际中inline函数很少使用)


12.递归函数
函数调用自己
必须有结束条件
栈操作


13.函数重载(overload)
重载函数至少在参数个数、类型、顺序上有所不同
尽量不要使用默认参数的函数,防止调用冲突


14.函数参数的const限定
可以防止在函数中修改某个传入参数的值


15.变量的作用域与可见性(☆)
局部变量:存于栈;函数调用完释放;作用域本函数内部
全局变量:存于全局数据区;程序结束释放;作用域本源文件、其他源文件使用时加extern声明
static局部变量:存于全局数据区;只在第一次调用函数时初始化一次;作用域本函数内部
static全局变量:存于全局数据区;程序结束释放;可见范围本源文件(其他源文件不可见)


16.头文件(.h)
声明函数
struct
class
enum
extern声明变量(使用其他源文件的全局变量)


17.进程空间
Data
Heap
Code
Stack


18.数组
只声明不初始化时,必须有元素个数
花括号初始化必须与声明放一起(花括号初始化时,元素个数可以省去)
花括号后的分号注意
字符数组初始化可用双引号
好习惯:memset(buf, 0x00, sizeof(buf)); //使用数组、结构时均可如此初始化内存


19.结构(struct)
用结构定义的结构名可以当成一种新数据类型使用

如:
struct Person{...;};
Person p1; // It's correct
struct Person p2; // It's correct too

注意定义结构时候最后的分号!!
结构之间可赋值
占用内存空间(Unix/windows下自然对界,结构大小必为最大成员的整数倍;Linux下只需整体补齐为int的整数倍)


20.指针
为防止野指针,一般声明指针时最好立即赋值(NULL)

注意*号的使用:
声明时:int* pi = NULL; // 此处星号表示变量pi为指针类型变量
赋值时:pi = &i; // 此处直接使用pi,pi变量存储的是地址0x...
使用时:*pi = 5; // 此处星号表示指针所指向的变量i,此语句等同于 i = 5;


21.结构取成员
结构变量取成员:p.id
指向结构的指针取成员:pp->id 或 (*pp).id


22.数组名其实是常量指针(不可进行自加减)


23.字符串操作(#i nclude )
strcpy(target, source);
strlen();
strcmp(target, source); //相同返回0
strncmp(target, source, n); //比较n个字符
strcat(target, source);


24.C风格字符串与C++风格字符串
C style string: char* or char []
C++ style string: string
(!!!注意:Unix C中,大部分库函数和系统函数还是使用C风格字符串)
这两种字符串可以相互转化:
C style to C++ style: string a = b;
C++ style to C style: char* b = a.c_str(); // 使用了c_str()函数,或使用data()函数


25.使用堆空间(heap)进行动态内存分配
int* p = new int[10];
delete[] p; // 只是释放p指向的内存,释放后的内存其他程序可以使用,否则内存泄漏
p = NULL; //将p指针赋为空,防止野指针


26.函数指针
!!!注意:函数指针是一个变量,不是一个函数

如:
void (*pf)(int, int); //pf是一个指针变量,只能指向void f(int, int)类的函数!!!
void f(int a, int b){...}
pf = f; //将f的首地址存入pf变量中!!!

函数指针一般只是用来声明函数的参数时使用
(即函数fa需要调用另一个函数fb时,将fb的函数指针放入声明fa的参数列表中)

如:
int fa(int a, void (*pf)(int, int)){...} //调用函数fa时,只能在第二个参数中传入一个类型为指向void f(int, int)函数的指针
void fb(int a, int b){...}
void (*pf)(int, int) = fb;
fa(5, pf);


27.void指针
一般作为函数声明时的函数参数,可增加函数通用性
不可进行自加减运算


28.常量指针指针常量
常量指针:const int* p; //p指向的数据不可变(p指向常量)
指针常量:int* const p; //p不可变(必须初始化)


29.引用
引用是一个变量的别名
声明:int& ri = i;
使用:ri = 5; //相当于使用i本身(i=5)
常用来做函数参数传递


30.typedef给类型起别名
步骤:
声明一个变量或函数
把名字改为别名
前加typedef

★C++面向对象特性


1.类
封装了函数成员的struct
(其实在C++中,struct内部也可以封装函数,但习惯上struct只封装数据,class可以封装数据和函数)
增加成员访问权限(public, private, protected)
类默认的是private(struct默认为public)
private=> 只能被本类或者友元访问
protected=> 只能被本类或者友元或者子类访问
public=>全部公开
外部定义类的成员函数用域作用符(::)
注意分号!!


2.构造函数(constructor)
创建对象时起初始化对象的作用
名字与类同
只能为public!!
无返回类型!!
可重载!!
没有时系统自动添加(一旦自己定义,系统不再添加)
可用冒号(:)引出初始化列表,如:
Person::Person(int a, int b):id(a), age(b){} //将成员id赋值为a, 将成员age赋值为b
struct也可以使用构造函数


3.拷贝构造函数(copy constructor)
系统默认存在一个拷贝构造函数,对成员依次拷贝(浅拷贝),有指针成员时危险
用一个已有对象对同类其他对象进行初始化
Person(const Person& pa);
使用:Person p2(p1); //相当于将p1所有成员赋值给p2


4.析构函数(destructor)
~类名(){}
无返回类型!!
不可重载!!
无参数!!
系统自动调用
做清理工作


5.继承
继承方式public, protected, private
class Derived:public Base{};
子类继承父类的所有成员,但是不能访问父类的private成员
public继承来的成员属性不变
protected继承来的成员public变为protected,其他不变
private继承来的全部变为private

继承中的构造函数,系统先调用父类再调用子类
子类
的构造函数可以给父类的构造函数传递参数,如:
Person::Person(int a, int b):id(a), age(b){}
Student::Student(int a, int b, int c):Person(a, b), grade(c){} //给父类的构造函数传递参数a, b

继承中的析构函数,系统先调用子类再调用父类

覆盖:子类中的函数会覆盖父类中的同名函数


6.多态与虚函数
为解决覆盖问题,将父类的函数声明为virtual型(虚函数),子类中再定义同名的函数
则使用指向父类指针指向子类对象时,调用该函数时,可自动识别对象类型,调用相应的子类中的函数
如:
virtual void Person::display(){cout << "Person" << endl;} //声明为virtual函数
void Student::display(){cout << "Student" << endl;}
Person* p = new Student;
p->display(); //调用子类的display
显示为“Student”


7.纯虚函数
若要父类的函数为空,只为了使用多态时,可以声明为纯虚函数
virtual void display() = 0;


8.多重继承与虚继承(菱形继承)(不常用)


9.类型转换算子详解
static_cast:void指针与其他类型指针间转换
const_cast:常量与变量之间转换
reinterpret_cast:指针与整型数据之间转换;任意类型指针之间转换
dynamic_cast:用于有继承关系且有虚函数的类之间的转换,子转父才能成功
格式:xxxx_cast(data)


10.抽象数据类型ADT
抽象类不能创建对象


11.友元(friend)
授权本类外部的函数或其他类可以使用本类的所有成员(包括private成员),使用时要用“对象.xxxx”


12.常量成员函数
类的成员函数参数列表后加上const,表示本函数为常量成员函数,不能修改本类的成员,如:
void display()const{} //display中不能修改本类的成员数据


13.静态成员
静态数据成员:所有对象使用一份数据;初始化放类外边(::);访问也用(::)
静态函数成员:相当于全局函数;只能访问静态数据成员;定义放类外边(::);访问用(::)


14.运算符重载
将“operator...”看成函数名,进行定义
返回类型不能为空!!
方法:成员或友元(尽量成员)
不能改变运算符的操作数(括号例外,括号的操作数特殊)
不能重载的运算符: . .* :: ?: sizeof # ##
操作基本类型的运算符不能重载(即运算符的操作数中至少应该有一个是自定义类型,如类)

只能用成员函数重载的:operator= operator[] operator() operator-> operator->*
成员函数重载时,默认的第一个操作数总是对象本身!!!所以参数列表的第一个操作数可以省去!!!

只能用友元函数重载的:operator<< operator>>
当第一个操作数非对象本身时,应使用友元!!!

下面详细介绍几个运算符的重载:

▲operator=
当类没有自定义operator=时,编译器自动生成一个,有指针成员时候危险
只能成员函数重载
常用格式:
A& operator=(const A& ao)
{
if (this == &ao) return *this; //判断this指针是否指向ao对象的地址
...=...;
*..=*..; //指针成员赋值其指向的变量
return *this;
}

▲operator++() and operator++(int) 前加与后加
定义这两个函数后,使用++a时调用前者,使用a++时调用后者
哑元区分
前加加的格式:
A& operator++() //使用引用
{
...++;
...++;
return *this;
}
后加加的格式:
A operator++(int dummy) //不能使用引用
{
A temp = *this;
...++;
...++;
return temp; //返回自加之前的值
}

▲双目运算符
作为成员函数重载时,第一个操作数必须是对象本身,且在参数列表中可以省去!!
当第一个操作数非对象本身时,应用友元法!!

▲operator()
特殊,操作数的个数不确定
使用时候类似函数,称为functor(仿函数),实际功能比函数还要强大

▲operator new/delete
较特殊,格式固定
static void* operator new(size_t sz){} //必须是static,返回void*
static void operator delete(void*){}
new和delete可同时带上[]

▲转换运算符
用于将一个对象转换为其他的数据类型
格式较特殊,不写返回类型(其类型名即为返回类型)
如:
operator double(){} //将返回double类型变量
使用:
double(ao);

▲operator<< and operator>>
这两个流操作符必须作为友元重载
格式较固定:
ostream& operator<< (ostream& o, A& ao)
{
o << .... << .... << ....;
return o;
}

istream& operator>> (istream& i, A& ao)
{
i >> .... >> .... >> ....;
return i;
}

15.main命令行参数模式
int main(int argc, char* argv[])
//argc指命令行参数的个数,包括命令本身
//argv存储了每个参数,包括命令本身即argv[0]
//argv为char*[]型,即char**型,或char[][]型,相当于二维字符数组或一维字符串数组

16.I/O标准流
(cin, cout, cerr, clog)
cin和cout支持缓冲,支持重定向
cerr为错误信息输出,不支持缓冲,不支持重定向
clog为日志输出,不支持重定向

cin详解:
cin >> //可连续使用;以空白(包括空格、回车、TAB)为分隔符
cin.get(char c) //可连续使用;获取任意单个字符,包括空白
cin.getline(char* buf, sizeof(buf), '\n') //可连续使用;获取一行,到最后指定的字符结束,可包括空白,默认回车
cin.gcount() //计数
cin.read(char* buf, sizeof(buf)) //可连续使用;读取指定大小的内容,包括空白;第一个参数必须为char*,可用强制转换
cin.ignore(1000, '\n') //忽略指定大小的内容,到制定字符结束忽略;常用来清空缓冲区
cin.clear() //清楚错误状态;常后跟ignore
if(!cin) //判断是否出错;cin为false则出错
cin.peek() //查看缓冲区下一个字符,但是不读取,即用get时候还可以读到
cin.putback() //将上一个读回的字符返回缓冲区,不常用

cout详解:
cout <<
控制符:endl, flush ....
cout.put(char)
cout.width(int) //一次性命令
cout.fill(char)
cout.precision(int)
cout.setf(ios::...)
cout.unsetf(ios::...)
(cout这些命令不常用,常用头文件中的函数代替)

:
setw(int) //设置宽度
setfill(char) //设置填充字符
setprecision(int) //设置精度,单用时表示总位数;与fixed连用时表示小数点后的位数

17.I/O文件流
(需包含头文件)

ifstream类:
使用:ifstream fin; //创建一个对象fin
cin中可以使用的函数在fin中同样可以使用
对cin的扩展:
构造函数可以制定文件名及打开方式
fin.open(...)
fin.read(...) //较多的使用此函数读取
fin.is_open() //检查是否打开成功,事实上经常用 if (!fin) 代替此函数
fin.eof() //判断是否超过文件末尾;超过末尾才返回true
fin.close() //关闭文件

ofstream类:
使用:ofstream fout;
常用打开方式有:ios::binary ios::app ios::out
(其余同上)


常用写/读格式:
fout.write((char*)&a, sizeof(a)); //将a对象的数据写入文件;注意强制类型转换(char*)
fin.read((char*)&b, sizeof(b)); //将文件中的内容读入到b对象的空间

18.异常(exception)
(#i nclude )
try
{
....;
if (....)
{
throw ....;
....; //不会执行此句
}
}
catch(....)
{
....;
}

注意:
catch捕获的异常为与throw同类型的数据
捕获异常后,程序在catch处理完异常后的地方继续执行,不会返回throw处
产生异常后,程序立即跳转,不会执行throw下的语句
如果没有catch捕获已经抛出的异常,最终内核捕捉到异常会将程序强制不正常关闭
catch(...)(括号中三个点)可以捕捉任何类型异常
异常的类型常使用内部类(inner class)来定义

19.内部类
内部类属于它所在的类的类成员(即类的静态成员),不属于某个对象
内部类的数据和它所在的类的数据互不相通

★数据结构


1.链表(LinkList)
由节点(node)构成,每个节点可以为一个struct,且该struct里可以封装进构造、析构等函数(而且常常如此)
每个节点可以如下定义:
struct Node
{
DATA data; // ADT
Node* next; //指向下一个节点的指针
Node(const DATA d) //构造函数初始化节点
{
data = d;
next = NULL;
}
};

每个链表由一个头指针head(Node* head;)进行访问

基本操作:增、删、查、改

▲插入节点(增):
Node* p = new Node; //分配新节点的空间
p->data = 0; p->next = NULL; //初始化新节点(此两句可以封装到Node的构造函数中)
//寻找要插入位置(即前一个Node的next指向的地址,假设为lp)
p->next = lp; //把新节点的next指向要插入位置的下一个节点
lp = p; //插入位置的前一个Node的next指向新节点
//插入成功

▲删除节点(删):
Node* temp = p->next; //将要删除节点的next指针(即p的下一个节点的地址)保存
delete p; //删除p的空间
lp = temp; //p节点的前一个节点的next指向p的下一个节点
//删除成功

▲查找节点(查):
Node* p = head; //从头指针开始遍历
while (p) //p不为NULL,就继续遍历
{
if (p->data == finddata) break;
p = p->next;
}
//缺点:如此查找到的p,只是在值上等于p前一个节点的next的值,而并非其前一个节点的next本身!!!
//想要得到前一个节点的next本身也很简单,只需要再定义一个指针,遍历时使该指针滞后一步
//如:
Node* p = head;
Node* lp = NULL; //总是滞后p一步
while (p)
{
if (p->data == finddata) break;
lp = p;
p = p->next;
}
//这样得到的lp就是p前一个节点的指针,lp->next和p的值应该相等,且lp->next是链表中的数据本身!!

▲修改节点(改):略

▲删除全部节点:
总是删除头节点的方法
Node* p = head;
while (p)
{
p = head->next; //将头节点的下一个节点的地址保存起来
delete head;
head = p;
}
//删除完成

▲operator[]:略


2.栈(stack)
LIFO(last in first out)
常用操作:push(), pop(), isempty(), clear()
(实际使用时,弹栈操作总是分离pop的功能为top和pop两个,top只管访问,pop只管删除)
可以用数组或链表实现
数组:下标
链表:前插前取


3.队列(queue)
FIFO(first in first out)
可以用数组或链表实现
数组:下标
链表:后插前取
优先队列(priority queue):插入时自动排序


4.二叉树(binary tree)
集数组和链表的优点:可以快速查找(数组);可以方便插入数据(链表)
每个节点最多有两个子节点
所以每个节点包含两个节点指针left和right
struct bNode
{
DATA data;
bNode* left;
bNode* right;
bNode(const DATA d) //constructor
{
data = d;
left = NULL;
right = NULL;
}
};

通过一个指向根节点root的指针(bNode* root;)访问
一般通过递归实现操作!!


5.二叉查找树(binary search tree)
左子节点(包括子节点的子节点)一定小于父节点
右子节点(包括子节点的子节点)一点大于或等于父节点

常用操作:增、遍历、删、查、改
一般均用递归法实现!!

▲插入节点(增):
void insert(bNode*& ptr, bNode* pnew) //ptr为树的待插入位置(必须使用指针的引用!!),pnew为待插入节点
{
if (ptr == NULL) //当树为空时;实为递归出口!!
{
ptr = pnew;
}
else if (pnew->data < ptr->data) //插入数据比该位置的数据小的时候,往左侧插入
{
insert(ptr->left); //递归调用
}
else //插入数据比该位置的数据大于或等于的时候,往右侧插入
{
insert(ptr->right); //递归调用
}
}
//插入成功


▲遍历:
void visit(bNode* ptr) //待遍历节点的指针,第一次调用时传入root指针
{
if (ptr == NULL) return; //递归出口
visit(ptr->left); //递归调用,遍历左侧
cout << ptr->data << endl; //输出本节点的内容
visit(ptr->right); //递归调用,遍历右侧
}
//遍历完成


▲清空二叉树:
void clear(bNode*& ptr) //待清空的节点的指针(必须使用指针的引用!!),第一次调用时传入root指针
{
if (ptr == NULL) return;
clear(ptr->left);
clear(ptr->right);
delete ptr;
ptr = NULL;
}
//清空成功


▲删除一个节点(删):
删除二叉查找树的一个节点较麻烦,常用方法有两种:降级法和替换法

降级法:将删除的节点的左子树挂入其右子树下边
替换法:将删除的机电的左子树下面最大的节点替换掉删除的节点

降级法实现代码:
void deleteNode(bNode*& ptr) //待删除的节点的指针的引用!!
{
bNode* p = ptr; //先将该节点的地址保存,以备后用
insert(ptr->left, ptr->right); //将左子树挂到右子树下面(参考insert函数)
ptr = ptr->right;
delete p; //删除节点的空间,用到刚才保存地址的p,因为此时ptr已经改变
}
//删除完成

替换法实现代码:
先写查找左子树下边最大节点的函数:
bNode*& findmax(bNode*& ptr) //返回类型必须为引用!!!
{
if (ptr->right == NULL) return ptr; //递归出口
findmax(ptr->right);
}
void deleteNode(bNode*& ptr)
{
bNode* p = ptr;
bNode*& pmaxref = findmax(ptr->left); //此处也必须使用引用!!!
bNode* pmax = pmaxref; //将pmaxref指向的节点的地址保存到pmax
pmaxref = NULL; //将左子树最大节点从树上摘下!!注意,操作的是引用!!!
ptr = pmax; //将要删除的节点的位置改为左子树最大节点;注意,操作的ptr为引用!!!
pmax->left = p->left;
pmax->right = p->right;
}
//删除完成

▲修改一个节点(改):先删除再插入

6.算法(algorithm)
算法分析、效率、时间复杂度、空间复杂度
大O表示法(Big O Notation):最多多少次
算法设计策略:蛮力法、递归法、贪心法等
查找:线性查找、二分法查找、索引查找
排序:选择排序、插入排序、冒泡排序、快速排序、希尔排序

排序方法详解:(按降序为例)

▲选择排序:
思路:第一轮排序将所有元素中最大的放在第一个,然后下一轮排序将剩余元素中最大的放到剩余元素的第一个,然后......
方法:双循环或递归

▲插入排序:
思路:认为第一个元素已经排好序,然后看下一个元素,如果比第一个大则排到其前边,否则排后边,依次下去......
实现起来较复杂

▲冒泡排序:
思路:每轮只比较相邻元素大小,前小后大则交换位置,这样比较多轮以后,直到不再发生任何交换时,排序结束
最慢的排序方法

▲快速排序:
思路:选出一个分界值(pivot),将大于分界值的移到左侧,小于分界值的移到右侧,一般可以使用递归
具体实现方法多种

▲库函数中的快速排序:(#i nclude ) (qsort)
qsort(int*, length, sizeof(int), (*compare));
//参数表依次为待排序的数组首地址、数组长度、数组的元素大小、比较函数的首地址
//比较函数需要自己定义

★自定义模板与标准模板库

1.自定义模板
使用模板是为了泛型编程
分为函数模板和类模板
定义模板时:
template //模板头;typename关键字可用class代替
...{} //函数体或类体中,可以将符号T当成一种数据类型

使用模板时:

函数模板可以根据传入参数的类型,自动识别类型
类模板需要将参数用尖括号传递:vector vi;

2.标准模板库(STL)
标准模板库包含以下内容:
container(容器)
algorithm(算法)
iterator(迭代器)
functor(仿函数)
adapter(容器配接器)
allocator(分配器)


3.container(容器)
用于存放一系列数据
分为Sequence Container和Associative Container两种
(序列式容器和关联式容器)

所有容器的共性:

都有三种构造函数(无参、拷贝、区间)
支持运算符:赋值(=)、比较(< <= > >= == !=)
支持交换函数swap(),对两个容器进行交换(s1.swap(s2);)
支持的操作:insert, erase, clear, empty(判断非空), size
都有四种迭代器:iterator, reverse_iterator, const_iterator, const_reverse_iterator
迭代器相关函数:begin, end, rbegin, rend


4.iterator(迭代器)
迭代器是一个容器的内部类,只封装了一个指针
外部访问容器的元素时,可以通过迭代器访问,所以迭代器的作用就是智能指针
迭代器内部重载的运算符一般有星号(*)、不等于(!=)、自加(++)、自减(--)四个运算符

迭代器与其所在的类的桥梁是一些迭代器相关函数(begin,end,rbegin,rend)等,带r的是反向

使用方法:

类名::iterator it; //声明一个迭代器对象
for (it=对象.begin; it!=对象.end; it++) {...} //以此来遍历一个容器


5.Sequence Container(序列式容器)
包括三种:vector, deque, list

▲序列式容器的共性:
构造函数可以指定个数及初始值
增加了resize(len)或resize(len, fillVal)
增加了insert(position, num, data)
增加了assign(num, data)
增加了取首尾函数:front(), back() (返回引用)
增加了后增删函数:push_back(data), pop_back()


▲vector:(#i nclude )
vector其实就是一个动态数组
支持[] (不检查越界)
支持at() (越界抛异常)
增加了capacity()函数 (容量)(有时!=size())
增加了reserve(len)函数 (调整容量)
用后插后取时效率较高


▲deque:(#i nclude )
deque其实是vector的增强版
增加了前增删函数:push_front(data), pop_front()
比vector减少了capacity和reserve函数


▲list:(#i nclude)
list其实是一个双向链表
不支持 [] 和 at()
只支持双向迭代器(++ --),不支持随机迭代器(+n -n)
增加了remove(data)(删除所有data节点)
增加了sort()(升序排序)
增加了reverse()(颠倒顺序)
增加了unique()(去掉相邻的重复元素,变为一个)
增加了merge(list2)(将list2保序合并到当前的list,list2变空,合并后排好序)
增加了splice(it, list2, list2.it1, list2.it2)(将list2中的区间转移到当前list的指定位置)
list适用于元素频繁插入删除的时候使用


6.Associative Container(关联式容器)
包括两种:map/multimap, set/multiset

▲关联式容器的共性:
实质为二叉查找树
可自动排序(要求容器元素的类型必须支持小于运算符)
每个元素都有一个key值
增加了insert(data)(不需指定位置)
增加了find(key)(返回第一个;若查不到,返回end())
增加了erase(key)(删除所有关键字为key的元素)
增加了count(key)
增加了lower_bound(key), upper_bound(key)
增加了equal_range(key)


▲map/multimap:(#i nclude


▲map/multimap插入元素方法:
插入对有四种方法:
insert(map::value_type("ABC", 100));
insert(pair("ABC", 100));
insert(make_pair("ABC", 100));
["ABC"] = 100;
(上述"ABC"为key, 100为value)
(注意:value_type为map类内部的函数)
(注意:pair为标准模板库中的一个类模板,其元素为first, second)
(注意:make_pair为标准库函数中的函数)
(注意:方括号运算符小心使用:若"ABC"不存在,则插入新的;若"ABC"已存在,在map中修改,在multimap中仍然插入新的)


▲set/multiset:(#i nclude )
每个元素只由一个key组成
set与multiset区别:同上

7.adapter(容器配接器)
#i nclude ==> stack
#i nclude ==> queue pqueue

使用:push(), pop, size(), empty()


8.algorithm(算法)
#i nclude ==> for_each find sort copy replace
#i nclude ==> min max accumulate swap

posted @ 2015-06-05 12:12  harry_ma  阅读(353)  评论(0编辑  收藏  举报
 aa
    部分内容来自网络,如有异议,请联系我.     


      成绩来自坚持, 灵感来自激情。

                                                               感谢父母和亲朋好友的爱与支持!