0%

考研复试

好好学习,好好生活!

笔试易考&易错点

1.switch case

要注意每个case中是否有break,如果没有,代码还会执行下面的case

2.static静态生存期(文件生存期)

普通数据类型

如果一个函数内定义一个静态数据类型,注意重复调用该函数时不会该数据类型只初始化一次

静态类对象

静态类对象执行到文件结束才会销毁从而调用析构函数,而非是main函数结束,所以一般是最后才析构,注意与普通类对象析构顺序

与普通静态数据类型一样,重复调用定义静态类对象的函数也不会重复建立该类对象

静态类对象单独一个栈

3.二维数组

1
2
3
int a[3][3];
int (*p)[3]=a; //一维数组来表示二维数组
*(*(p+j)+i); //表示p[j][i]

4.字符操作

1
*str!=0; //是将str指向字符对于的ascii码与0比较,'\0'对于整型0,'0'->48,'A'->65,'a'->97
1
2
*str-'\0'; //将字符'0'-'9'变成整型0-9,同理也能进行大小写转换
*str-'a'+'A';//将小写转化成大写
1
2
3
4
5
//常用函数
strlen(str);//计算字符串长度,'\0'不算入长度,但sizeof会算入'\0'
strcpy(str1,str2);//将字符串str2赋值给str1,如果是int类型数组,只能通过for循环将str2值赋值给str1
strcat(str1,str2);//将字符串str2拼接到str1后面
strcmp(str1,str2);//字符串str1指向值大于str2,返回大于0,反之,返回小于0,相等返回0,比较方法,逐位比较字符对于ascii码

5.派生类的构造与析构

构造顺序

1
2
3
按照继承顺序调用先基类的构造函数,如果初始化列表给出参数,则还要传入参数;
若派生类包含基类的对象(不是指针对象)要再次调用基类构造函数;(指针对象,通常是进入派生类构造函数后通过new再调用基类构造函数)
最后再执行派生类构造函数代码

析构顺序

1
2
如果基类的构造函数不是虚函数,则只调用基类的析构函数
若基类的构造函数是虚函数,则按与构造相反的顺序调用析构函数

菱形继承中基类的初始化

1
2
B,C虚继承A,D又继承B和C;D中只有一份A,在D的构造函数初始化列表中,若有单独的A(x)初始化,则直接按这个参数调用,
若没有,按照继承顺序,由先调用B再调用A执行基类构造函数 火火P220 题4

复制构造函数

不调用复制构造函数的情况

1
2
3
1.A a=A(); //临时对象这里只调用构造函数然后再析构,A ~A
2.返回值是类对象
3.函数实参是临时对象比如调用fun,fun(A()),形参fun(A a),与第一种一样

有派生类B继承A

1
2
3
4
5
6
7
B b;
A a=b; //此时会调用复制构造函数,将b中A类子对象复制给a

A a=B(); //创建临时对象后要销毁,先调用A构造再调用B构造,再调用A复制构造,再看A析构函数是否为虚函数进行析构
若是,则整个顺序是 A B Acopy ~B ~A;若不是,则整个顺序是A B Acopy ~A

A* p=new B; //new新建堆上对象,调用顺序是A B,只有当遇到delete主动删除时,才要析构,析构个数还取决于基类是否为虚析构函数

6.类对象转换

1
2
3
4
5
6
7
8
//类B继承类A
B b;
A* p=&b; //调用同名函数时看是否为虚函数进行相应的调用(要满足虚函数覆盖的要求,类名,参数个数,参数对应类型都要一样)
A& p2=&b; //与指针一样

A p3=b;//调用同名函数时只会调用基类的函数,无多态性(注意这里要调用复制构造偶)

//b调用同名函数时会进行隐藏基类函数,从而调用自己类内函数(隐藏只需要函数同名即可)

7.字符数组/字符串数组/字符指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const char* chr="abcd"; //表示不能修改chr[i],但可以修改chr,chr="bcde"

//字符的输出与其他类型不一样
char arr[10] = { 'a','b' };
cout << arr; //输出ab
const char* chr="abcd";
cout<<chr; //输出abcd

//对于int类型
int arr[10] = { 1,2 };
cout << arr; //输出地址
int a = 10;
int* p = &a;
cout <<p; //输出地址

//字符串数组
const char* a[] = { "123","456","789" };
const char** p = a; //a指向的数据类型是cosnt char*,而a又是地址,所以p是const char**
p++;
cout<<*p; //输出456
//另一种
const char* p2 = a[2]; //a[2]是const char*,所以p2也是const char*
p2++;
cout<<p2; //输出89

8.文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//头文件
#include<fstream>

//从文件中读取
ifstream infile;
infile.open("文件名",ios::in);
if(!infile)cout<<"file not open"; //一定要判断
char buf[100];
infile.getline(buf,100);
infile.close(); //一定要关闭
//文件打开操作换成文件路径
ifstream infile("文件路径");

//从标准输入中读取
cin.getline(buf,100);

//写入文件
ofstream outfile;
outfile.open("文件名",ios::app);
if(!outfile)cout<<"file not open"; //一定要判断
outfile<<"写入的字符";
outfile.close();

算法部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//二分查找(非递归版)
int binarySearch(int* arr, int len,int x) {
int low = 0;
int high = len - 1;
int mid = (low + high) / 2;
while (low <= high) {
if (arr[mid] > x) high = mid - 1;
else if (arr[mid] < x) low = mid + 1;
else return mid;
}
if (low > high)return -1;
}
//递归版
template <typename T>
T binarySearch(T* arr, int low, int high, T x) {
int mid = (low + high) / 2;
if (arr[mid] > x)return binarySearch(arr, low, mid - 1, x);
else if (arr[mid] < x)return binarySearch(arr, mid + 1, high, x);
else return mid;
}
1
2
3
4
5
6
7
8
//冒泡排序
for(int i=0;i<len-1;i++){
for(int j=0;j<len-1-i;j++){
if(a[j]>a[j+1]){
swap(a[j],a[j+1]);
}
}
}
1
2
3
4
5
6
7
8
9
//插入排序,升序
for (int i = 0; i < size - 1; i++) {
for (int j = i; j >= 0; j--) {
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
else
break;
}
}
1
2
3
4
5
6
7
8
9
10
11
//选择排序,升序
for (int i = 0; j < size-1; i++) {
int pos=i;
for(int j=i+1;j<n;j++){
if(a[j]<a[pos])
pos=j;
}
int temp=a[pos];
a[pos]=a[i];
a[i]=temp;
}

STL库

STL之vector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//迭代器:
vector<int> v = {1, 2, 3, 4, 5};
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
//遍历插入push_back()
for (auto it = v1.begin(); it != v1.end(); ++it) {
v2.push_back(*it);
}
//通过size遍历赋值
for(int i=0;i<v.size();i++){
v2[i]=v[i];
}
//算法copy
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2(v1.size()); // 先开空间
copy(v1.begin(), v1.end(), v2.begin()); //从v2.begin()开始的原有数据会被覆盖
//算法sort,默认升序
sort(v.begin(), v.end());
//算法reverse
reverse(v.begin(), v.end());

STL之string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//定义和初始化
string s1; // 空字符串
string s2 = "hello";
string s3(5, 'a'); // "aaaaa"
//访问字符
s[i];
//字符串修改
s += "world";
s = s1 + s2;
s.insert(2, "abc"); // 在下标2插入
s.erase(2, 3); // 从下标2删除3个字符
//查找
int pos = s.find("abc"); //找到 → 下标
//长度与状态
s.size();
s.length(); // 等价
s.empty();

概念

1
2
3
4
5
封装:将数据和操作数据的方法放在同一个类中,并通过访问控制隐藏内部实现细节
类接口:是类对外部提供的功能集合,描述了类可以完成哪些操作
继承:用于描述类之间的层次关系,派生类可以在基类的基础上拓展新功能
多态:是指通过基类指针或引用调用虚函数时,实际执行的函数由对象的真实类型决定
数据与处理逻辑分离:是指将数据的表示方式与对数据的操作逻辑进行合理划分
# #