2024年C C++最全C++基础篇之STL库(一)—(1),2024年最新2024年C C++社招面试题

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!


* 现代写法



string& operator=(const string& s)
{
if (this != &s)
{
//string tmp(s); // 调用拷贝构造
string tmp(s._str); // 调用构造函数

	//std::swap(\_str, tmp.\_str);
	//std::swap(\_size, tmp.\_size);
	//std::swap(\_capacity, tmp.\_capacity);
	swap(tmp);	
}
return \*this;

}


在现代写法的基础上进一步改进,在传参的时候不传引用,便会调用拷贝构造初始化形参`s`,将`s`和`*this`进行交换即可,出了作用域,形参s自动调用析构函数进行销毁。



string& operator=(string s)
{
//std::swap(_str, s._str);
//std::swap(_size, tmp._size);
//std::swap(_capacity, tmp._capacity);
swap(s);
return *this;
}


### 析构函数


析构函数只需要把申请的空间销毁即可



~string()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}


## string类迭代器


迭代器按功能分为:


* iterator
* const\_iterator
* reverse\_iterator
* const\_reverse\_iterator



typedef char* iterator;
typedef const char* const_iterator;

typedef reverse_iterator<const_iterator, const char&, const char*>const_reverse_iterator;
typedef reverse_iterator<iterator, char&, char*> reverse_iterator;


反向迭代器库函数实现:



int main()
{
string s1(“sherry”);
string::iterator it = s1.begin();
while (it != s1.end())
{
*it -= 1;
++it;
}
cout << endl;

it = s1.begin();
while (it != s1.end())
{
	cout << \*it << " ";
	++it;
}
cout << endl;

// 反向迭代器
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{
	cout << \*rit << " ";
	++rit;
}
cout << endl;

}


***模拟实现***



iterator begin()
{
return _str;
}

iterator end()
{
return _str + _size;
}

const_iterator begin() const
{
return _str;
}

const_iterator end() const
{
return _str + _size;
}


## string类容量操作


string类的容量改变使用reserve和resize函数。


### reserve函数


![在这里插入图片描述](https://img-blog.csdnimg.cn/a665142d4ae940679bb1e8272058c5ed.png)  
 reserve函数是为string预留n个字节空间,不改变有效元素(\_size)的个数。  
 **注意:当reserve的参数小于string底层空间大小时,reserve不会改变容量(\_capacity)大小。**  
 ***模拟实现***



void reserve(size_t n)
{
if (n > _capacity)
{
char* tmp = new char[n + 1];
strcpy(tmp, _str);
delete[] _str;

	_str = tmp;
	_capacity = n;
}

}


### resize函数


![在这里插入图片描述](https://img-blog.csdnimg.cn/6225135628224068b98ece672654736e.png)  
 std库中的resize函数有两种方式,第一种是将字符串中有效字符个数改变到n个,用0来填充多余的元素空间;第二种是用字符c来填充多余的元素空间。  
 **注意:如果改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小(\_capacity)是不变的。**  
 ***模拟实现***



void resize(size_t n, char ch = ‘\0’)
{
if (n <= _size)
{
_str[n] = ‘\0’;
_size = n;
}
else
{
if (n > _capacity)
{
reserve(n);
}
memset(_str + _size, ch, n - _size);
_str[n] = ‘\0’;
_size = n;
}
}


## string类插入


### push\_back


pusk\_back尾插函数,每次向string类字符串尾插一个字符。



string s1;
s1.push_back(‘x’);
s1.push_back(‘y’);
s1.push_back(‘z’);


***模拟实现***



void push_back(char ch)
{
if (_size == _capacity)
{
// 增容
reserve(_capacity == 0 ? 4 : _capacity * 2);
}
_str[_size] = ch;
++_size;
_str[_size] = ‘\0’;

//insert(\_size, ch);

}


### append


append函数可以在string类字符串后增加字符串。



string s1(“hello”);
s1.append(" world");


***模拟实现***



void append(const char* str)
{
// 增容
size_t len = strlen(str);
if (_size + len > _capacity)
{
reserve(_size + len);
}

strcpy(_str + _size, str);
_size += len;

//insert(\_size, str);

}


### +=


string中重载了+= 运算符,因为+=更加人性化。  
 +=函数服用了push\_back和append函数。



string s1;
s1 += ‘x’;
s1 += " ";
s1 += “yyy”;


***模拟实现***



string& operator+=(char ch)
{
push_back(ch);
return *this;
}
string& operator+=(const char* str)
{
append(str);
return *this;
}


### insert


![在这里插入图片描述](https://img-blog.csdnimg.cn/baab3d8b6b5a4d9a8d05e88e829ce26f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2hlcnJ5LTc3,size_20,color_FFFFFF,t_70,g_se,x_16)



string s1(“hello”);
s1.insert(0, 1, ’ ');
s1.insert(6, “world”);


***模拟实现***



string& insert(size_t pos, char ch)
{
assert(pos <= _size);
if (_size == _capacity)
{
reserve(_capacity == 0 ? 4 : _capacity * 2);
}
size_t end = _size + 1;
while(end > pos)
{
_str[end] = _str[end - 1];
–end;
}
_str[pos] = ch;
++_size;

return \*this;

}

string& insert(size_t pos, const char* str)
{
assert(pos <= _size);
size_t len = strlen(str);
if (_size + len > _capacity)
{
reserve(_size + len);
}
size_t end = len + _size;
while(end >= pos + len)
{
_str[end] = _str[end - len];
–end;
}
strncpy(_str + pos, str, len);
_size += len;

return \*this;

}


## string类删除


![在这里插入图片描述](https://img-blog.csdnimg.cn/9ad6b3dfa2944fd2b84a86bfdb2f06fc.png)  
 第一种erase()函数有两个参数,第一个是删除位置,第二个是删除长度,缺省值代表将后面的字符串全部删除;第二种erase()函数的参数是迭代器,可以传入迭代器,删除当前迭代器位置的字符;



string s2(“hello world”);
s2.erase(0, 1);
s2.erase(s2.begin());


删除分为两种情况,第二种删除当前位置及其之后的所有字符,这时只需要把pos位置置为’\0’即可;第二种删除某一段字符,这时候涉及到字符的挪动。  
 ***模拟实现***



string& erase(size_t pos = 0, size_t len = npos)
{
assert(pos < _size);
if (len == npos || pos + len > _size)
{
_str[pos] = ‘\0’;
_size = pos;
}
else
{
strcpy(_str + pos, _str + pos + len);
_size -= len;
}
return *this;
}


## string类查找


string类的查找函数find,可以查找一个字符,也可以在指定位置开始查找字符串。



size_t find(char ch);
size_t find(const char* str, size_t pos = 0)


***模拟实现***



size_t find(char ch)
{
for (size_t i = 0; i < _size; i++)
{
if (ch == _str[i])
{
return i;
}
}
return npos;
}

size_t find(const char* str, size_t pos = 0)
{
const char* ptr = strstr(_str + pos, str);
if (ptr == nullptr)
{
return npos;
}
else
{
return ptr - _str;
}
}


## []运算符重载


string类最方便的在于可以随机访问,而可以想数组一样随机访问字符串中的任意位置,是因为重载了[]运算符。  
 ***模拟实现***



char& operator[](size_t pos)
{
assert(pos < _size);
return _str[pos];
}

const char& operator[](size_t pos) const
{
assert(pos < _size);
return _str[pos];
}


## 流插入<<和流提取>>运算符重载


为了实现能够对string类的流插入和流提取,我们在string类外定义流插入和流提取函数。如果在类内实现,类的成员函数第一个参数默认是this,就只能实现成s1 >> cin(s1 << cout),不符合我们的使用习惯。


![img](https://img-blog.csdnimg.cn/img_convert/587918bdcc7f882043f9d24c59e1e0f1.png)
![img](https://img-blog.csdnimg.cn/img_convert/a8a120f1edb8d86d5a92a0719abaf4a7.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

s) const
{
	assert(pos < _size);
	return _str[pos];
}

流插入<<和流提取>>运算符重载

为了实现能够对string类的流插入和流提取,我们在string类外定义流插入和流提取函数。如果在类内实现,类的成员函数第一个参数默认是this,就只能实现成s1 >> cin(s1 << cout),不符合我们的使用习惯。

[外链图片转存中…(img-wALxQr4G-1715523589712)]
[外链图片转存中…(img-iw410a1M-1715523589713)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值