当前位置: 首页 > wzjs >正文

网站大事记时间轴折叠动画设计和动漫设计一样吗

网站大事记时间轴折叠,动画设计和动漫设计一样吗,官方网站建设需求规格说明书,网页定制哪家不错目录 一、std::string类的基本使用(常用) 1.1、初始化与赋值 1.2、字符串的拼接 1.3、string类对象的访问及遍历操作 1.4、长度与容量操作 1.5、子字符串与查找 1.6、string类非成员函数 二、模拟实现string类核心功能 2.1、类定义与成员变量 …

目录

一、std::string类的基本使用(常用)

1.1、初始化与赋值

1.2、字符串的拼接

1.3、string类对象的访问及遍历操作

1.4、长度与容量操作

1.5、子字符串与查找

1.6、string类非成员函数

二、模拟实现string类核心功能

2.1、类定义与成员变量

2.2、构造与析构函数

2.3、深拷贝

2.4、扩容机制

三、完整代码


为什么需要std::string类?

在C语言中字符串是通过字符数组来管理的,虽然C标准库提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不符合面向对象编程的思想。并且需要手动内存管理(容易内存泄漏或越界),缺乏便捷的操作(查找之类的),无法动态调整大小。

string类的优势:

而在C++中,string作为标准库容器,能自动内存管理,提供了很多接口函数,还集成了STL的算法(algorithm)库。使用起来更便捷、安全。

一、std::string类的基本使用(常用)

1.1、初始化与赋值

1.2、字符串的拼接

               函数名称                                                功能
        push_back在字符串后尾插个字符C
        append在字符串后追加一个字符串
        oprator+=在字符串后追加字符串

比如:

1.3、string类对象的访问及遍历操作

可以通过多种方式访问和修改字符

        函数名                                                功能
       operator[]

返回pos位置的字符

            at()返回pos位置的字符
 begin() 、end()begin获取一个字符的迭代器 、 end获取最后一个字符下一个位置的迭代器
rbegin()、rend()begin获取一个字符的迭代器 、 end获取最后一个字符下一个位置的迭代器

这里operator[]与at()区别在于at会进行边界检查,如果超过边界,编译器会抛异常。前者不检查边界

1.4、长度与容量操作

        函数名                                                        功能
        size返回字符串有效字符长度
        length返回字符串有效字符长度
       capacity        返回空间总大小
        empty检查字符串是否为空串,是返回true,否则返回false
        clear清空有效字符
        reserve为字符串预留空间(扩容)
       resize将有效字符改为n个,多出的空间用字符c填充

注意:

1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。

2. clear()只是将string中有效字符清空,不改变底层空间大小。

3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的 元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小。

1.5、子字符串与查找

        函数名                                                功能
        find从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
        rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
 find_first_of在字符串中查找字符(从前往后找)
find_last_of在字符串中查找字符(从后往前找)
        substr在str中从pos位置开始,截取n个字符,然后将其返回
       c_str将 C++ 字符串转换为 C 风格字符串(即以空字符 \0 结尾的字符数组)

const char* c_str() const,

返回指向字符串内部字符数组的 const char* 指针

#include <string>
#include <stdio.h>int main() 
{std::string s = "Hello World";const char* cstr = s.c_str();printf("%s\n", cstr); // 输出 "Hello World"return 0;
}

1.6、string类非成员函数

        函数名                                                        功能
     operator+尽量少用,因为传值返回,导致深拷贝效率低
    operator>> 输入运算符重载
    operator<<输出运算符重载
    getline获取一行字符串
relational operators大小比较

operator>>无法读取包含空格的整行文本(遇到空格停止)。

std::string s;
std::cin >> s;  // 输入 "Hello World" 时,s = "Hello"

getline:

从输入流中读取整行文本(包括空格),直到遇到换行符或指定分隔符。

std::string s;
std::getline(std::cin, s);         // 默认以换行符分隔
std::getline(std::cin, s, ';');     // 读取直到遇到分号

relational operators(重载比较运算符):

比较两个字符串的字典序,支持 ==!=<><=>=

std::string a = "apple";
std::string b = "banana";
if (a < b) {  // true,"apple" 字典序小于 "banana"// ...
}

按 ASCII 码值比较。


二、模拟实现string类核心功能

2.1、类定义与成员变量

class string 
{
private:size_t _capacity;  // 当前分配的内存容量size_t _size;      // 字符串实际长度(不含'\0')char* _str;        // 动态分配的字符数组
public:const static size_t npos = -1;  // 表示无效位置的常量
};

2.2、构造与析构函数

构造函数:

使用memcpy而非strcpy,避免字符串中间存在 \0 导致截断。

参数 “ ” 是确保空字符串初始化为 \0.

析构函数:


2.3、深拷贝

拷贝构造:

赋值运算符重载:

避免if (this != &s)导致的资源错误释放。

2.4、扩容机制


三、完整代码

#pragma once#include<assert.h>
#include<iostream>
using namespace std;namespace lsg
{class string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}/*string():_capacity(0), _size(0), _str(new char[1]){_str[0] = '\0';}*/string(const char* s = "")//空字符串是有一个\0的:_capacity(strlen(s)),_size(_capacity),_str(new char[_capacity+1]){//strcpy(_str, s);memcpy(_str, s, _size + 1);}//拷贝构造string(const string& s){_str = new char[s._capacity + 1];//strcpy(_str, s._str);这个不行,要是string对象中间有'\0','\0'后面的也是应该要拷贝的memcpy(_str, s._str, s._size + 1);_size = s._size;_capacity = s._capacity;}//实现的是深拷贝string& operator=(const string& s){if (this != &s){char* tmp = new char[s._capacity + 1];memcpy(_str, s._str, s._size + 1);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}const char* c_str() const{return _str;}size_t size() const{return _size;}char& operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}void reserve(size_t len){//如果传过来的len小于_capacity不缩括if (len > _capacity){char* tmp = new char[len + 1];//strcpy(tmp, _str);这个也一样memcpy(tmp, _str, _size + 1);delete[] _str;_str = tmp;_capacity = len;}}void resize(size_t n, char ch = '\0'){if (n < _size){_size = n;_str[_size] = '\0';}else{reserve(n);for (size_t i = _size;i < n;i++){_str[i] = ch;}_size = n;_str[_size] = '\0';}}void push_back(const char ch){if (_size == _capacity){//2倍扩容reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = ch;_size++;_str[_size] = '\0';}void append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){//至少扩到—_size+lenreserve(_size + len);}//strcpy(_str + _size, str);//可换可不换memcpy(_str + _size, str, len + 1);_size += len;}string& operator+=(char ch){push_back(ch);return *this;}string& operator+=(const char* str){append(str);return *this;}void insert(size_t pos, size_t n, const char ch){assert(pos <= _size);//扩容if (_size + n > _capacity){reserve(_size + n);}//挪数据int end = _size;//while (end >= (int)pos)//当pos==0时要强转,整型提升while (end >= pos && end != npos)//end==-1等于npos{_str[end + n] = _str[end];end--;}//插数据for (int i = 0;i < n;i++){_str[pos + i] = ch;}_size += n;}void insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (len + _size > _capacity){reserve(len + _size);}//挪数据int end = _size;while (end >= pos && end != npos){_str[end + len] = _str[end];--end;}//插入数据for (int i = 0;i < len;i++){_str[pos + i] = str[i];}_size += len;}void erase(size_t pos, size_t len = npos){assert(pos <= _size);if (len == npos || pos + len > _size){_str[pos] = '\0';_size = pos;}else{size_t end = pos + len;while (end <= _size){_str[pos++] = _str[end++];}_size -= len;}}size_t find(char ch, size_t n = 0){assert(n <= _size);for (size_t i = n;i < _size;i++){if (_str[i] == ch){return i;}}return npos;}size_t find(const char* str, size_t n = 0){assert(n <= _size);const char* ptr = strstr(_str, str);if (ptr){return ptr - _str;}else{return npos;}}string substr(size_t pos = 0, size_t len = npos){assert(pos <= _size);size_t n = len;if (len == npos || pos + len > _size){n = _size - pos;}string tmp;tmp.reserve(n);for (size_t i = pos;i < pos + n;i++){tmp += _str[i];}return tmp;}void clear(){_str[0] = '\0';_size = 0;}bool operator<(const string& s) const {int ret = memcmp(_str, s._str, _size < s._size ? _size : s._size);//"hello" "hello"  false//"helloxx" "hello" false//"hello" "helloxx"  truereturn ret == 0 ? _size < s._size : ret < 0;}bool operator==(const string& s) const{return _size == s._size && memcmp(_str, s._str, _size) == 0;}bool operator<=(const string& s) const{return *this < s || *this == s;}bool operator>(const string& s) const{return !(*this <= s);}bool operator>=(const string& s) const {return !(*this < s);}bool operator!=(const string& s) const{return !(*this == s);}private:size_t _capacity;size_t _size;char* _str;public:const static size_t npos;};const size_t string::npos = -1;
}ostream& operator<<(ostream& out, const lsg::string& s)
{/*for (size_t i = 0;i < s.size();i++){out << s[i];}*/for (auto ch : s){out << ch;}return out;
}istream& operator>>(istream& in, lsg::string& s)
{//s.clear();//每次流提取前要覆盖掉之前的//char ch = in.get();in >> ch;//这样读不到空格和换行//while (ch != ' ' && ch != '\n')//{//	s += ch;//	ch = in.get();//}//优化######################################s.clear();//每次流提取前要覆盖掉之前的char ch = in.get();//处理前缓冲区的空格和换行while (ch == ' ' || ch == '\n'){ch = in.get();}char buff[128];int i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[i] = '\0';s += buff;i = 0;}ch = in.get();}if (i != 0){buff[i] = '\0';s += buff;}return in;
}


文章转载自:

http://KWBZ9ldv.htjwz.cn
http://axAo4zBj.htjwz.cn
http://GxG3OKYg.htjwz.cn
http://nHUsT0zV.htjwz.cn
http://vWK8xFrP.htjwz.cn
http://UISqbTmQ.htjwz.cn
http://vZelaDAh.htjwz.cn
http://0JRhPRjc.htjwz.cn
http://o1a9QAZQ.htjwz.cn
http://z95BfTXd.htjwz.cn
http://BtJfN7S0.htjwz.cn
http://8rMh8CFV.htjwz.cn
http://uuUPoZF1.htjwz.cn
http://j3hVwdg8.htjwz.cn
http://wQuR3NSj.htjwz.cn
http://ehoPV2XR.htjwz.cn
http://ZarnHKsW.htjwz.cn
http://XZxQZaf4.htjwz.cn
http://QOdU3xdT.htjwz.cn
http://Jjc9BwM8.htjwz.cn
http://x6LXJ2Jj.htjwz.cn
http://ydXAALwd.htjwz.cn
http://gfjMuRaR.htjwz.cn
http://Bx0nyvHm.htjwz.cn
http://Q0kQjjNg.htjwz.cn
http://RoEP8jxv.htjwz.cn
http://V8Qdf6Mb.htjwz.cn
http://iaWy8QHr.htjwz.cn
http://RMwI7paV.htjwz.cn
http://cGefZAYF.htjwz.cn
http://www.dtcms.com/wzjs/659253.html

相关文章:

  • 青岛网站制作多少钱一个拉新工作室在哪里接项目
  • 辽宁网站建设价位网络营销工具的分类
  • 一站式网站设计易语言如何建设网站
  • 教学督导网站建设报告西乡做网站费用
  • 能看网站的浏览器为什么要用php做网站
  • 用dreammwea怎么做视频网站360网站推广官网球阀
  • 马鞍山市网站建设简单网站系统
  • 保定网站排名网站建设管理策划书
  • 深圳宝安区有几个街道厦门市做网站优化
  • 企业网站的网址通常包括asp旅游网站模板下载
  • 网站设计建设合同是wordpress 替换主题
  • 保险网站程序源码做网站用html还是php
  • 我想找个做代理的网站推动门户网站建设不断优化升级
  • 哪个网站做图片外链城镇建设周刊网站
  • 微信导购网站怎么做视频教学备案 通过后 网站打不开
  • 网站建设百灵鸟优化wordpress分类页面空白
  • 网站建设欣赏上海公司注册商标流程及费用
  • 网站管理公司排名wordpress gallery
  • 网站搜索功能怎么实现长沙网站关键词优化
  • 公司介绍网站源码构建一个网站需要多少钱
  • wordpress建立手机网站做视频网站要什么
  • 福建省住建厅建设网站软件app开发需要多少钱
  • 电子商务网站建设概述台州公司网站建设
  • 找人做网站域名怎么过户企业建站的目的是什么
  • 企业营销系统和网站建设WordPress编辑器过滤
  • 网站建设标题怎么查看网站死链
  • 帮企业做网站赚钱怎么制作微信链接
  • 郑州网站建设zzwzjs顶尖的赣州网站建设
  • 做电影种子下载网站违法吗wordpress网站如何搬家
  • 有谁用2008做网站服务器网站建设费预付定金什么科目