门户网站用什么源码,山东建设项目环境影响登记网站,怎么做品牌推广和宣传,企业网站用个人备案枫の个人主页
你不能改变过去#xff0c;但你可以改变未来
算法/C/数据结构/C Hello#xff0c;这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕#xff0c;我们继续来学习C的内容呀。C是接近底层有比较经典的语言#xff0c;因此学习起来注定枯燥无味#xf… 枫の个人主页
你不能改变过去但你可以改变未来
算法/C/数据结构/C Hello这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕我们继续来学习C的内容呀。C是接近底层有比较经典的语言因此学习起来注定枯燥无味西游记大家都看过吧~我希望能带着大家一起跨过九九八十一难降伏各类难题学会C我会尽我所能以通俗易懂、幽默风趣的方式带给大家形象生动的知识也希望大家遇到困难不退缩遇到难题不放弃学习师徒四人的精神故此得名【C游记】 话不多说让我们一起进入今天的学习吧~~~ 目录 1标准库的String
1.1auto和范围for小知识
1.2string常用接口组件这里都可以查找到
容量接口
访问和遍历 string类对象的修改操作
非成员函数但会用到
2string的模拟实现 3Boos战——string重要接口的模拟实现
1.String.h
2.String.cpp
3.wctest.cpp
4结语 1标准库的String
1.1auto和范围for小知识 师傅别怕赠与“武器”一把 i auto基本知识 它声明引用类型时必须在auto后加上。 声明多个变量时这些变量必须是相同的类型。 auto不能作为函数参数可以作为返回值。 不能用于声明数组。 #includeiostream
using namespace std;
int main() {auto a 10;auto b b;auto c asdofih;auto d 11.11;auto e a;cout a endl;cout b endl;cout c endl;cout d endl;cout e endl;printf(%p %p, a, e);return 0;
} 范围for 对比C语言的for循环C使用更好用的范围for代替 格式为“forauto 范围内用于迭代的变量 : 被迭代的范围”自动迭代、取数据、结束这就是自动范围for。
#includeiostream
using namespace std;
int main() {int arr[] { 1,2,3,4,5 };for (auto e : arr) {//若要更改里面的数值那么就要用引用才能修改到数组本身e 2;}for (auto e : arr) {cout e ;}cout endl;string str(hello world);for (auto ch : str) {cout ch ;}cout endl;return 0;
} 1.2string常用接口组件这里都可以查找到 师傅后面都会介绍不必担心 String函数名称功能说明string构造空的string类对象即空字符串stringconst char* s用C-string常量字符串来构造string类对象stringsize_t n,char c string类对象中包含n个字符c stringconst strings) 拷贝构造函数
void Test1() {string s1;//构造空的string类对象string s2(hello feng);//用常量字符串构造string类对象string s3(s2);//用s2拷贝构造s3
}
容量接口
若定义为string s以下表size为例就是s.size();
size返回字符串有效字符长度使用范围比length广length返回字符串有效字符长度capacity返回总空间大小empty检测字符串释放为空串空返回true非空返回falseclear清空有效字符reserve为字符串预留空间resize将有效字符个数设置为n个多余用c填充 补充说明size和length的区别只有在引入迭代器才能体现出来一般都用sizelength有使用限制。 clear只清空不改大小 resizesize_t n,char c用变量c的字符填充多余空间resizesize_t则是用0来填充。 reserve预留空间小于string的空间大小时不作改动。 访问和遍历
函数名称功能说明operator[]返回pos位置的字符const string类对象调用beginendbegin获取一个字符的迭代器end获取最后一个字符下一个位置的迭代器rbeginrendrbegin获取最后一个字符的迭代器rend获取一个字符的迭代器范围forC11的遍历方式 string类对象的修改操作
函数名称 功能说明 push_back在字符串后尾插字符c单个append在字符串后追加一个字符串多个operator在字符串后追加一个字符串多个c_str返回C格式字符串findnpos从字符串pos位置往后查找字符c返回它的位置rfind从字符串pos位置往前查找字符c返回它的位置substr在str中从pos位置开始截取n个字符将其返回
非成员函数但会用到
函数 功能说明 operator深拷贝效率低operator输入运算符重载operator输出运算符重载getline获取一行字符串relational operators大小比较
2string的模拟实现
错误示范
#includeiostream
#includeassert.h
using namespace std;
class MyString {
public:MyString(const char* str ) {if (str nullptr) {perror(flase);return;}_str new char[strlen(str) 1];//加1放\0strcpy(_str, str);}~MyString() {if (_str) {delete[] _str;_str nullptr;}}
private:char* _str;
};
void Test2() {string s1(hello feng);string s2(s1);
}int main() {/*Test1();*/Test2();return 0;
}
上述过程会报错因为没有写拷贝构造s2会调用s1的默认构造而在类和对象章节中我们知道默认构造都是浅拷贝这里是一个字符数组因此要调用深拷贝。
#includeiostream
#includeassert.h
using namespace std;
class MyString {
public:MyString(const char* str ) {//构造if (str nullptr) {perror(flase);return;}_str new char[strlen(str) 1];//加1放\0strcpy(_str, str);}MyString(const MyString s)//拷贝构造:_str(nullptr){MyString tmp(s._str);swap(tmp._str, _str);}~MyString() {//析构if (_str) {delete[] _str;_str nullptr;}}
private:char* _str;
};
void Test2() {string s1(hello feng);string s2(s1);
}int main() {/*Test1();*/Test2();return 0;
} 3Boos战——string重要接口的模拟实现 这里直接附上上个文件源码大部分已经注释完毕请大家伙享用感兴趣可以复制过去测试不过还是自己敲一遍比较好。 1.String.h
#pragma once#includeiostream
#includeassert.h
#includestring.h
using namespace std;namespace wc
{class string{public:typedef char* iterator;//手动自造迭代器名字与库中相同但在wc的命名空间里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;}void swap(string s);//交换直接套用标准库里的swapstring(size_t n, char ch);//设置相同字符多少个为一个字符串string(const char* str );//构造函数string(const string s);//拷贝构造函数~string();//析构函数void clear()//清除{_str[0] \0;_size 0;}string operator(string s);//string operator(const string s);const char* c_str() const//常数直接返回自己地址比较快因此调用内联{return _str;}void reserve(size_t n);//保存为字符串预留空间void push_back(char ch);//类似于尾插void append(const char* str);//尾插一个字符串string operator(char ch);//类似于尾插string operator(const char* str);//尾插一个字符串void insert(size_t pos, size_t n, char ch);//在pos位置插入n个ch字符void insert(size_t pos, const char* str);//在pos位置插入一个字符串void erase(size_t pos 0, size_t len npos);//在pos位置删除len个字符size_t find(char ch, size_t pos 0);size_t find(const char* str, size_t pos 0);size_t size() const{return _size;}size_t capacity() 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];}string substr(size_t pos, size_t len npos);//从pos位置开始取len个作为子串返回bool operator(const string s) const;bool operator!(const string s) const;bool operator(const string s) const;bool operator(const string s) const;bool operator(const string s) const;bool operator(const string s) const;private:char* _str nullptr;//定义字符串数组_strsize_t _size 0;//有效个数size_t _capacity 0;//总容量const static size_t npos;//设置默认结束值};// couts1ostream operator(ostream out, const string s);// cins1istream operator(istream in, string s);istream getline(istream is, string s, char delim \n);void test_string1();void test_string2();void test_string3();void test_string4();void test_string5();void test_string6();void test_string7();
}
2.String.cpp
//#includeiostream
//using namespace std;
//int main() {
// auto a 10;
// auto b b;
// auto c asdofih;
// auto d 11.11;
// auto e a;
// cout a endl;
// cout b endl;
// cout c endl;
// cout d endl;
// cout e endl;
// printf(%p %p, a, e);
// return 0;
//}
//#includeiostream
//using namespace std;
//int main() {
// int arr[] { 1,2,3,4,5 };
// for (auto e : arr) {//若要更改里面的数值那么就要用引用才能修改到数组本身
// e 2;
// }
// for (auto e : arr) {
// cout e ;
// }
// cout endl;
// string str(hello world);
// for (auto ch : str) {
// cout ch ;
// }
// cout endl;
// return 0;
//}//void Test1() {
// string s1;//构造空的string类对象
// string s2(hello feng);//用常量字符串构造string类对象
// string s3(s2);//用s2拷贝构造s3
//}
//#includeiostream
//#includeassert.h
//using namespace std;
//class MyString {
//public:
// MyString(const char* str ) {//构造
// if (str nullptr) {
// perror(flase);
// return;
// }
// _str new char[strlen(str) 1];//加1放\0
// strcpy(_str, str);
// }
// MyString(const MyString s)//拷贝构造
// :_str(nullptr)
// {
// MyString tmp(s._str);
// swap(tmp._str, _str);
// }
// ~MyString() {//析构
// if (_str) {
// delete[] _str;
// _str nullptr;
// }
// }
//private:
// char* _str;
//};
//void Test2() {
// string s1(hello feng);
// string s2(s1);
//}
//
//int main() {
// /*Test1();*/
// Test2();
// return 0;
//}#define _CRT_SECURE_NO_WARNINGS 1
#includestring.hnamespace wc
{const size_t string::npos -1;void string::swap(string s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}string::string(size_t n, char ch):_str(new char[n 1]), _size(n),_capacity(n){for (size_t i 0; i n; i) {_str[i] ch;}_str[_size] \0;}string::string(const char* str)//声明中写过默认值这里就不能再写了 :_size(strlen(str)){_capacity _size;_str new char[_size 1];strcpy(_str, str);//复制还没复制\0_str[_size] \0;}string::string(const string s){string tmp(s._str);swap(tmp);}string::~string(){delete[] _str;_str nullptr;_size 0;_capacity 0;}string string::operator(string s) {swap(s);return *this;}void string::reserve(size_t n) {//预留空间if (n _capacity) {//大于就扩容char* tmp new char[n 1];strcpy(tmp, _str);delete[] _str;_str tmp;_capacity n;}}void string::push_back(char ch) {if (_size 1 _capacity) {//大于就扩容reserve(_capacity 0 ? 4 : _capacity * 2);//预留空间刚写就能用}_str[_size] ch;_size;_str[_size] \0;}void string::append(const char* str) {size_t len strlen(str);if (_size len _capacity) {reserve(_size len);}strcpy(_str _size, str);_size len;}string string::operator(char ch){push_back(ch);return *this;}string string::operator(const char* str){append(str);return *this;}void string::insert(size_t pos, size_t n, char ch){assert(pos _size);assert(n 0);if (_size n _capacity){// 扩容size_t newCapacity 2 * _capacity;if (_size n 2 * _capacity){newCapacity _size n;}reserve(newCapacity);}size_t end _size n;while (end pos n - 1) {_str[end] _str[end - n];end--;}for (size_t i 0; i n; i) {_str[pos i] ch;}_size n;}void string::insert(size_t pos, const char* str){size_t n strlen(str);insert(pos, n, x);//覆盖一下for (size_t i 0; i n; i){_str[pos i] str[i];}}void string::erase(size_t pos, size_t len) {if (len _size - pos) {//多删了_str[pos] \0;_size pos;}else {size_t end pos len;while (end _size) {//\0也拷贝_str[end - len] _str[end];end;}_size - len;}}size_t string::find(char ch, size_t pos){for (size_t i pos; i _size; i){if (_str[i] ch){return i;}}return npos;}size_t string::find(const char* str, size_t pos){const char* p strstr(_str pos, str);if (p nullptr){return npos;}else{return p - _str;}}string string::substr(size_t pos, size_t len){if (len _size - pos)//若超出就等于剩下长度len _size - pos;string tmp;tmp.reserve(len);for (size_t i 0; i len; i) {tmp _str[pos i];//直接加等简单易懂}return tmp;}bool string::operator(const string s) const{return strcmp(_str, s._str) 0;}bool string::operator!(const string s) const{return !(*this s);}bool string::operator(const string s) const{return strcmp(_str, s._str) 0;}bool string::operator(const string s) const{return *this s || *this s;}bool string::operator(const string s) const{return !(*this s);}bool string::operator(const string s) const{return !(*this s);}ostream operator(ostream out, const string s){for (size_t i0;is.size();i){out s[i];}return out;}istream operator(istream in, string s){s.clear();// 输入短串不会浪费空间// 输入长串避免不断扩容const size_t N 1024;char buff[N];int i 0;char ch in.get();while (ch ! ch ! \n)//遇到空格和\n停止{buff[i] ch;if (i N - 1){buff[i] \0;//最后一个复制为0然后加上s buff;i 0;}//也可以直接写sch不过占用内存高ch in.get();}if (i 0){buff[i] \0;s buff;}return in;}istream getline(istream in, string s, char delim){s.clear();const size_t N 1024;char buff[N];int i 0;char ch in.get();while (ch ! delim){buff[i] ch;if (i N - 1){buff[i] \0;s buff;i 0;}ch in.get();}if (i 0){buff[i] \0;s buff;}return in;}void test_string1(){string s1(hello world);cout s1.c_str() endl;string s2;cout s2.c_str() endl;s1 ;s1 ;s1 hello ;s1 hello feng1111111111111111111111111;cout s1.c_str() endl;}void test_string2(){string s1(hello world);cout s1.c_str() endl;s1.insert(11, 3, x);cout s1.c_str() endl;s1.insert(6, 3, x);cout s1.c_str() endl;s1.insert(0, 3, x);cout s1.c_str() endl;string s2(hello world);cout s2.c_str() endl;s2.insert(11, yyy);cout s2.c_str() endl;s2.insert(6, yyy);cout s2.c_str() endl;s2.insert(0, yyy);cout s2.c_str() endl;}void test_string3(){string s1(hello world);cout s1.c_str() endl;s1.erase(6, 2);cout s1.c_str() endl;s1.erase(6, 20);cout s1.c_str() endl;s1.erase(3);cout s1.c_str() endl;string s2(hello helleoo);cout s2.find(e) endl;cout s2.find(helle) endl;}void test_string4(){string s1(hello world);for (size_t i 0; i s1.size(); i){s1[i];cout s1[i] ;}cout endl;string::iterator it s1.begin();while (it ! s1.end()){cout *it ;it;}cout endl;for (auto e : s1){cout e ;}cout endl;const string s2(hello world);for (auto e : s2){cout e ;}cout endl;}void test_string5(){string s1(hello world);string sub1 s1.substr(6, 3);cout sub1.c_str() endl;string sub2 s1.substr(6, 300);cout sub2.c_str() endl;string sub3 s1.substr(6);cout sub3.c_str() endl;string s2(hello fengxxxxxxxxxxxxxxxxxx);s1 s2;cout s1.c_str() endl;cout s2.c_str() endl;s1 s1;cout s1.c_str() endl;}void test_string6(){/*string s1(hello world);string s2(hello bit);cout s1 endl;cout s2 endl;string s3;cin s3;cout s3 endl;*/string s1, s2;cin s1 s2;cout s1 endl;cout s2 endl;string s3;//getline(cin, s3);getline(cin, s3, !);cout s3 endl;}void test_string7(){string s1(1111111111111);string s2(s1);cout s1 endl;cout s2 endl;string s3(222222222222222222222222222);s1 s3;cout s1 endl;cout s3 endl;//s1.swap(s2);//swap(s1, s2);cout s1 endl;cout s2 endl;}
}
3.wctest.cpp
#includestring.hint main()
{//wc::test_string1();//wc::test_string3();wc::test_string5();return 0;
}
4结语 今日C到这里就结束啦如果觉得文章还不错的话可以三连支持一下。感兴趣的宝子们欢迎持续订阅小枫小枫在这里谢谢宝子们啦~小枫の主页还有更多生动有趣的文章欢迎宝子们去点评鸭~C的学习很陡时而巨难时而巨简单希望宝子们和小枫一起坚持下去~你们的三连就是小枫的动力感谢支持~