文章目录
0. 目标完成情况
- unp第2章和第3章看完 ---------- 两天了还是没怎么看,这两天处于面试适应期,效率低下,有点懒,以后每天不管怎样都要更新博客日记。
- 看看面经
- LeetCode 一道题
1. 所学回顾
1.1 C++的析构函数为什么要设成虚函数
是为了在使用父类指针来调用析构函数的时候,调用的是动态类型对象的析构函数,而不是按照静态类型来调用。
如果按照静态类型来调用的话,那么就仅仅是调用父类的析构函数了,这会导致子类的析构函数没有被执行,从而导致内存泄露。而如果按照动态类型来调用,就是调用的实际子类的析构函数,从而可以先执行子类的析构函数,再执行父类的析构函数,避免了内存泄露。
这里还录制了一个小视频。
1.2 栈中存放什么
栈分为用户栈和内核栈。
- 内核栈:当程序从用户模式进入内核模式的时候,会将返回地址、一些处理器状态压入内核栈。
- 用户栈:当过程调用的时候,会将返回地址、一些处理器状态压入用户栈,在函数执行的过程中,栈中会存放函数内的局部变量。
总结: 如果笼统地问栈中存放什么,应该答:局部变量、返回地址和一些处理器状态。 (今天面试只想起来局部变量,没想起来返回地址,很遗憾。)
实际上,如上图所示,在main函数之前,还会存放shell字符串,环境变量。
1.3 未初始化的静态变量存在哪里
在.bss段
初始化了的在.data段
代码段在.text段
1.4 螺旋数组
题目如下图:
我的代码如下,为简单起见,没有考虑越界问题。
#include<iostream>
#include<vector>
using namespace std;
int fun(vector<vector<int>>& nums, int x, int y){
int x0=0, y0=0;
// 找到1所在的位置
for(int i=0; i<nums.size(); i++){
for(int j=0; j<nums.size(); j++){
if(nums[i][j] == 1){
x0=i;
y0=j;
break;
}
}
}
int i=0, j=0; // i和j为相对的横纵坐标
int step = 1;
while(i!=x || j!=y){
for(int up = 0; up<step; up++){
i++;
if(i == x && j == y) return nums[x0-j][y0+i];
}
for(int left = 0; left<step; left++){
j--;
if(i == x && j == y) return nums[x0-j][y0+i];
}
step++;
for(int bot = 0; bot<step; bot++){
i--;
if(i == x && j == y) return nums[x0-j][y0+i];
}
for(int right = 0; right<step; right++){
j++;
if(i == x && j == y) return nums[x0-j][y0+i];
}
step++;
}
}
int main(){
vector<vector<int>> res = {
{20, 7, 8, 9, 10},
{19, 6, 1, 2, 11},
{18, 5, 4, 3, 12},
{17, 16,15,14,13},
};
cout << fun(res,-2, -1) << endl;
}
1.5 string类的实现
主要实现了几个基本的构造和运算,拷贝都是深拷贝,暂时没有考虑copy on write问题。
代码如下,可以直接运行:
#include<iostream>
#include<cstring>
using namespace std;
class String{
private:
char* m_p;
public:
String(const char* str = nullptr);
String(const String& str);
~String();
String& operator=(const String& str);
String operator+(const String& str);
bool operator==(const String& str);
char operator[](int index);
int getLength();
char* getMp() const {
return this->m_p;
}
};
String::String(const char* str){
if(str == nullptr){
this->m_p = 0;;
}else{
this->m_p = new char[strlen(str) + 1];
strcpy(this->m_p, str);
}
}
String::String(const String& str){
if(str.m_p == nullptr){
this->m_p = nullptr;
}else{
this->m_p = new char[strlen(str.m_p) + 1];
strcpy(this->m_p, str.m_p);
}
}
String::~String(){
if(this->m_p){
delete[] this->m_p;
this->m_p = 0;
}
}
String& String::operator=(const String& str){
if(this->m_p != nullptr){
delete[] this->m_p;
}
if(str.m_p == nullptr){
this->m_p = 0;
}else{
this->m_p = new char[strlen(str.m_p) + 1];
strcpy(this->m_p, str.m_p);
}
}
String String::operator+(const String& str){
String res;
if(str.m_p == nullptr){
res = *this;
}else if(this->m_p == nullptr){
res = str;
}else{
res.m_p = new char[strlen(this->m_p) + strlen(str.m_p) + 1];
strcpy(res.m_p, this->m_p);
strcat(res.m_p, str.m_p);
}
return res;
}
bool String::operator==(const String& str){
if(this->m_p == nullptr && str.m_p == nullptr) return true;
if(strlen(this->m_p) != strlen(str.m_p)) return false;
if(strcmp(this->m_p, str.m_p) == 0) {
return true;
}else {
return false;
}
}
char String::operator[](int index){
if(index < strlen(this->m_p) && index > 0){
return this->m_p[index];
}
}
int String::getLength(){
return strlen(this->m_p);
}
ostream& operator << (ostream& os, const String& str){ // 全局函数
os << str.getMp();
return os;
}
int main(){
String str = String("hello");
cout << str << "\t" << str.getLength() << endl;
String str2 = String(" world!");
cout << str2 <<"\t" << str2.getLength() << endl;
cout << str + str2 << endl;
cout << (str2 == str)<< endl;
cout << str[3] << endl;
}
2. 明日(5月13日)目标
- 上午:复习智能指针的实现、vector的实现
- 下午:牛客2道题,leetcode每日一题。有时间看一节侯捷的stl视频。
- 晚上:unp第三章看完。
- 一定一定要写博客。