这段代码中grade为什么没用全局定义,仍然能够在加减函数中使用?如果fix it 不适用 win 10student类,怎么定义grade?

君,已阅读到文档的结尾了呢~~
win32课后习题答案与提示,课后习题答案网,土力学课后习题答案,统计学课后习题答案,微积分课后习题答案,c语言课后习题答案,测量学课后习题答案,课后习题答案,概率论课后习题答案,矩阵论课后习题答案
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
win32课后习题答案与提示
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口C++不支持嵌套函数(像Pascal,Java等都支持),这给编程带来很大麻烦。
使用嵌套函数相对于全局函数有很多好处:
嵌套函数只在外层函数中有效,防止将函数作为全局函数而污染全局函数空间,使全局函数数量膨胀
嵌套函数只在外层函数中有效,程序员只需要了解外层函数即可,程序员需要了解的函数数量将减少
嵌套函数只在外层函数中有效,可以定义多个同名同原型的嵌套函数,而不会像全局函数那样只能一个
使用嵌套函数将使外层函数层次更加清晰。
使用嵌套函数的唯一缺点是不能在多个函数之间共享(那是全局函数要做的事情),容易在各个外层函数中使用复制粘贴来定义函数。
程序要根据不同使用场合来决定一个函数应该是全局函数还是嵌套函数。原则是:
1.凡是需要在多个函数中共享的,一般都定义为全局函数
2.如果一个全局函数只被另外一个函数调用,那么考虑将这个函数改为调用者的嵌套函数
3.如果一个函数体过长,可以考虑按照一定的逻辑将其划分为几个嵌套函数
4.如果一个函数体有重复编码一段代码,那么考虑将这段代码提取成为一个嵌套函数
有关全局函数和嵌套函数的说明一般也适合于一个类,从类的空间来说,类的成员函数相当于全局函数。
当应用于类的时候,使用类成员函数还是嵌套函数还需要考虑一下几点:
1.由于类有自己的命名空间,一般不会污染全局函数空间
2.如果不想让程序员了解更多内层函数,将其声明成private或者protected
3.如果一个成员函数只被另一个成员函数调用,可以这个函数改为调用者的嵌套函数,
& 如果这个函数需要访问类的数据成员,则需要传递this指针,或者可以考虑仍然为成员函数
4.将过长成员函数体分割为几个嵌套函数时,可能也需要传递体this指针
下文介绍一种C++中支持函数嵌套的变通方法:
首先,将下面两段宏拷贝到需要使用嵌套函数的地方(如StdAfx.h文件的末尾):
//////////////////////////////////////////////////////////////////////////////
#define BEGIN_NEST_FUNCTION(ReturnType, FunName, ParamListWithRoundBrackets) \
struct Functor_##FunName \
&ReturnType operator() ParamListWithRoundBrackets const
#define END_NEST_FUNCTION(FunName) \
static const Functor_##FunName FunN
//////////////////////////////////////////////////////////////////////////////
FunName是函数的名称,
ReturnType是函数的返回值,
ParamListWithRoundBrackets是参数列表,必须用圆括号括起来(...),如果没有参数列表,也必须用空的圆括号()
其次,在某一个函数中使用BEGIN_NEST_FUNCTION和END_NEST_FUNCTION宏,将函数体扩起来,例如:
void main()
&&&& //定义一个嵌套函数Add,返回值是int,参数是int a 和 int b,参数列表要用括号括起来
&&&& BEGIN_NEST_FUNCTION(int, Add, (int a, int b))
&&&&&&&&& return a+b;
&&& END_NEST_FUNCTION(Add);
&//调用嵌套函数
&int c = Add(1, 2);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3070次
排名:千里之外
(1)(1)(1)(1)(1)(1)C/C++基础 达内学习笔记
C/C++基础 达内学习笔记
发布时间: 13:28:01
编辑:www.fx114.net
本篇文章主要介绍了"C/C++基础 达内学习笔记",主要涉及到C/C++基础 达内学习笔记方面的内容,对于C/C++基础 达内学习笔记感兴趣的同学可以参考一下。
★C/C++基础
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(!!)
第一个字母必须是字母或下划线
只能使用字母或下划线或数字
中间不能有空格
不能是保留字,不能与库函数重名
区分大小写
4.基本数据类型
char=& unsigned/signed char
int=& unsigned/signed long/short int
float=& double, long double
5.四个类型转换算子(详细见后面)
static_cast:
const_cast:
reinterpret_cast:
dynamic_cast:
优先级前三名:() .或-& 单目
优先级后三名: ?: = 逗号
7.枚举类型
enum color{RED, BLUE=10, GREEN}; // 默认数值为0, 1, 2...这样改变值后为0, 10, 11...
color c = GREEN;
8.表达式(略)
9.控制语句
if(){}else{}
do{}while();
switch(){}
函数三要素:返回类型、函数名、参数表
声明(无函数体;参数表参数可无参数名,但必须有类型)
定义(有函数体{})
调用函数实际是利用栈操作,执行完一个函数时候,栈释放
使用默认参数(必须从右至左指定默认值)
11.内联函数(inline)
编译时,只是将内联函数的代码粘贴到调用处,不进行栈操作,所以速度快
必须声明与定义放一起
不支持控制语句(所以实际中inline函数很少使用)
12.递归函数
函数调用自己
必须有结束条件
13.函数重载(overload)
重载函数至少在参数个数、类型、顺序上有所不同
尽量不要使用默认参数的函数,防止调用冲突
14.函数参数的const限定
可以防止在函数中修改某个传入参数的值
15.变量的作用域与可见性(☆)
局部变量:存于栈;函数调用完释放;作用域本函数内部
全局变量:存于全局数据区;程序结束释放;作用域本源文件、其他源文件使用时加extern声明
static局部变量:存于全局数据区;只在第一次调用函数时初始化一次;作用域本函数内部
static全局变量:存于全局数据区;程序结束释放;可见范围本源文件(其他源文件不可见)
16.头文件(.h)
extern声明变量(使用其他源文件的全局变量)
17.进程空间
只声明不初始化时,必须有元素个数
花括号初始化必须与声明放一起(花括号初始化时,元素个数可以省去)
花括号后的分号注意
字符数组初始化可用双引号
好习惯: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的整数倍)
为防止野指针,一般声明指针时最好立即赋值(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);
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 =
C++ style to C style: char* b = a.c_str(); // 使用了c_str()函数,或使用data()函数
25.使用堆空间(heap)进行动态内存分配
int* p = new int[10];
delete[] // 只是释放p指向的内存,释放后的内存其他程序可以使用,否则内存泄漏
p = NULL; //将p指针赋为空,防止野指针
26.函数指针
!!!注意:函数指针是一个变量,不是一个函数
void (*pf)(int, int); //pf是一个指针变量,只能指向void f(int, int)类的函数!!!
void f(int a, int b){...}
pf = //将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) =
fa(5, pf);
27.void指针
一般作为函数声明时的函数参数,可增加函数通用性
不可进行自加减运算
28.常量指针和指针常量
常量指针:const int* //p指向的数据不可变(p指向常量)
指针常量:int* //p不可变(必须初始化)
引用是一个变量的别名
声明:int& ri =
使用:ri = 5; //相当于使用i本身(i=5)
常用来做函数参数传递
30.typedef给类型起别名
声明一个变量或函数
把名字改为别名
前加typedef
★C++面向对象特性
封装了函数成员的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)
无返回类型!!
不可重载!!
系统自动调用
做清理工作
继承方式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& &&} //声明为virtual函数
void Student::display(){cout && &Student& &&}
Person* p = new S
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指针是否指向ao对象的地址
*..=*..; //指针成员赋值其指向的变量
▲operator++() and operator++(int) 前加与后加
定义这两个函数后,使用++a时调用前者,使用a++时调用后者
前加加的格式:
A& operator++() //使用引用
...++;
...++;
后加加的格式:
A operator++(int dummy) //不能使用引用
A 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 && .... && .... && ....;
istream& operator&& (istream& i, A& ao)
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 && //可连续使用;以空白(包括空格、回车、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详解:
控制符: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类:
使用: //创建一个对象fin
cin中可以使用的函数在fin中同样可以使用
对cin的扩展:
构造函数可以制定文件名及打开方式
fin.open(...)
fin.read(...) //较多的使用此函数读取
fin.is_open() //检查是否打开成功,事实上经常用 if (!fin) 代替此函数
fin.eof() //判断是否超过文件末尾;超过末尾才返回true
fin.close() //关闭文件
ofstream类:
常用打开方式有: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 )
throw ....;
....; //不会执行此句
catch(....)
catch捕获的异常为与throw同类型的数据
捕获异常后,程序在catch处理完异常后的地方继续执行,不会返回throw处
产生异常后,程序立即跳转,不会执行throw下的语句
如果没有catch捕获已经抛出的异常,最终内核捕捉到异常会将程序强制不正常关闭
catch(...)(括号中三个点)可以捕捉任何类型异常
异常的类型常使用内部类(inner class)来定义
内部类属于它所在的类的类成员(即类的静态成员),不属于某个对象
内部类的数据和它所在的类的数据互不相通
★数据结构
1.链表(LinkList)
由节点(node)构成,每个节点可以为一个struct,且该struct里可以封装进构造、析构等函数(而且常常如此)
每个节点可以如下定义:
struct Node
DATA // ADT
Node* //指向下一个节点的指针
Node(const DATA d) //构造函数初始化节点
next = NULL;
每个链表由一个头指针head(Node*)进行访问
基本操作:增、删、查、改
▲插入节点(增):
Node* p = new N //分配新节点的空间
p-&data = 0; p-&next = NULL; //初始化新节点(此两句可以封装到Node的构造函数中)
//寻找要插入位置(即前一个Node的next指向的地址,假设为lp)
p-&next = //把新节点的next指向要插入位置的下一个节点
lp = //插入位置的前一个Node的next指向新节点
//插入成功
▲删除节点(删):
Node* temp = p-& //将要删除节点的next指针(即p的下一个节点的地址)保存
//删除p的空间
lp = //p节点的前一个节点的next指向p的下一个节点
//删除成功
▲查找节点(查):
Node* p = //从头指针开始遍历
while (p) //p不为NULL,就继续遍历
if (p-&data == finddata)
//缺点:如此查找到的p,只是在值上等于p前一个节点的next的值,而并非其前一个节点的next本身!!!
//想要得到前一个节点的next本身也很简单,只需要再定义一个指针,遍历时使该指针滞后一步
Node* lp = NULL; //总是滞后p一步
if (p-&data == finddata)
//这样得到的lp就是p前一个节点的指针,lp-&next和p的值应该相等,且lp-&next是链表中的数据本身!!
▲修改节点(改):略
▲删除全部节点:
总是删除头节点的方法
p = head-& //将头节点的下一个节点的地址保存起来
//删除完成
▲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
bNode(const DATA d) //constructor
left = NULL;
right = NULL;
通过一个指向根节点root的指针(bNode*)访问
一般通过递归实现操作!!
5.二叉查找树(binary search tree)
左子节点(包括子节点的子节点)一定小于父节点
右子节点(包括子节点的子节点)一点大于或等于父节点
常用操作:增、遍历、删、查、改
一般均用递归法实现!!
▲插入节点(增):
void insert(bNode*& ptr, bNode* pnew) //ptr为树的待插入位置(必须使用指针的引用!!),pnew为待插入节点
if (ptr == NULL) //当树为空时;实为递归出口!!
else if (pnew-&data & ptr-&data) //插入数据比该位置的数据小的时候,往左侧插入
insert(ptr-&left); //递归调用
else //插入数据比该位置的数据大于或等于的时候,往右侧插入
insert(ptr-&right); //递归调用
//插入成功
void visit(bNode* ptr) //待遍历节点的指针,第一次调用时传入root指针
if (ptr == NULL) //递归出口
visit(ptr-&left); //递归调用,遍历左侧
cout && ptr-&data && //输出本节点的内容
visit(ptr-&right); //递归调用,遍历右侧
//遍历完成
▲清空二叉树:
void clear(bNode*& ptr) //待清空的节点的指针(必须使用指针的引用!!),第一次调用时传入root指针
if (ptr == NULL)
clear(ptr-&left);
clear(ptr-&right);
ptr = NULL;
//清空成功
▲删除一个节点(删):
删除二叉查找树的一个节点较麻烦,常用方法有两种:降级法和替换法
降级法:将删除的节点的左子树挂入其右子树下边
替换法:将删除的机电的左子树下面最大的节点替换掉删除的节点
降级法实现代码:
void deleteNode(bNode*& ptr) //待删除的节点的指针的引用!!
bNode* p = //先将该节点的地址保存,以备后用
insert(ptr-&left, ptr-&right); //将左子树挂到右子树下面(参考insert函数)
ptr = ptr-&
//删除节点的空间,用到刚才保存地址的p,因为此时ptr已经改变
//删除完成
替换法实现代码:
先写查找左子树下边最大节点的函数:
bNode*& findmax(bNode*& ptr) //返回类型必须为引用!!!
if (ptr-&right == NULL) //递归出口
findmax(ptr-&right);
void deleteNode(bNode*& ptr)
bNode* p =
bNode*& pmaxref = findmax(ptr-&left); //此处也必须使用引用!!!
bNode* pmax = //将pmaxref指向的节点的地址保存到pmax
pmaxref = NULL; //将左子树最大节点从树上摘下!!注意,操作的是引用!!!
ptr = //将要删除的节点的位置改为左子树最大节点;注意,操作的ptr为引用!!!
pmax-&left = p-&
pmax-&right = p-&
//删除完成
▲修改一个节点(改):先删除再插入
6.算法(algorithm)
算法分析、效率、时间复杂度、空间复杂度
大O表示法(Big O Notation):最多多少次
算法设计策略:蛮力法、递归法、贪心法等
查找:线性查找、二分法查找、索引查找
排序:选择排序、插入排序、冒泡排序、快速排序、希尔排序
排序方法详解:(按降序为例)
▲选择排序:
思路:第一轮排序将所有元素中最大的放在第一个,然后下一轮排序将剩余元素中最大的放到剩余元素的第一个,然后......
方法:双循环或递归
▲插入排序:
思路:认为第一个元素已经排好序,然后看下一个元素,如果比第一个大则排到其前边,否则排后边,依次下去......
实现起来较复杂
▲冒泡排序:
思路:每轮只比较相邻元素大小,前小后大则交换位置,这样比较多轮以后,直到不再发生任何交换时,排序结束
最慢的排序方法
▲快速排序:
思路:选出一个分界值(pivot),将大于分界值的移到左侧,小于分界值的移到右侧,一般可以使用递归
具体实现方法多种
▲库函数中的快速排序:(#i nclude ) (qsort)
qsort(int*, length, sizeof(int), (*compare));
//参数表依次为待排序的数组首地址、数组长度、数组的元素大小、比较函数的首地址
//比较函数需要自己定义
★自定义模板与标准模板库
1.自定义模板
使用模板是为了泛型编程
分为函数模板和类模板
定义模板时:
template //模板头;typename关键字可用class代替
...{} //函数体或类体中,可以将符号T当成一种数据类型
使用模板时:
函数模板可以根据传入参数的类型,自动识别类型
类模板需要将参数用尖括号传递:
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的是反向
使用方法:
类名:: //声明一个迭代器对象
for (it=对象. it!=对象. 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
★Core C++小结
经过15天标准C++学习,大概内容基本上到此结束,或许有些具体细节还不甚明白(比如xxx_cast等),不过已经窥探了C++的全貌,尽得其精
要。老师说过,学习编程,最重要的是学习编程思想,用强烈的逻辑思维来思考事情。所以一些语法的细节不必深究,只需明白C++的特性、特
长、特点,去思考Bjarne Stroustrup为什么给C++设计这么多特性,这就够了。具体要用某个函数时,不明白就去查阅相关文档即可。
这段时间的另一个收获是,陈宗权老师的一句话:生活中怎么去想,编程时就怎么去想;怎么去想,就怎么去编码。
经过这段时间的编程练习,感觉到这句话确实可以作为编程思想的最大的概括,一切编程方法,都是从现实生活中继承而来的。
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:}

我要回帖

更多关于 小针刀不适用人群 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信