informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Daftar isi
1. Mengapa mempelajari kelas string?
2. Kelas string di perpustakaan standar
2.2 Deskripsi antarmuka umum kelas string
1. Konstruksi umum objek kelas string
2. Operasi pada objek kelas string
3. Deskripsi struktur string pada vs dan g++
3. Implementasi simulasi kelas string
3.5 Implementasi simulasi kelas string
https://cplusplus.com/referensi/string/string/?kw=string
- void Teststring()
- {
- string s1; // 构造空的string类对象s1
- string s2("hello bit"); // 用C格式字符串构造string类对象s2
- string s3(s2); // 拷贝构造s3
- }
Catatan:
- 1. ukuran() danpanjang()Prinsip penerapan yang mendasari metode ini sama persis, yaitu memperkenalkanukuran()Alasannya adalah agar konsisten dengan antarmuka container lain. Umumnya, size() digunakan.。
- 2. clear() baru saja mengonversirangkaianKarakter valid di dalamnya dihapus dan ukuran ruang di bawahnya tidak diubah.
- 3. mengubah ukuran(ukuran_t n) dan ubah ukuran(ukuran_t n, char c)Semuanya mengubah jumlah karakter valid dalam string menjadiNPerbedaannya adalah ketika jumlah karakter bertambah: resize(n)menggunakan0untuk mengisi ruang elemen tambahan,ubah ukuran(ukuran_t n, char c)dengan karakterC untuk mengisi ruang elemen tambahan. Catatan: ubah ukuranKetika jumlah elemen diubah, jika jumlah elemen bertambah, ukuran kapasitas di bawahnya dapat diubah. Jika jumlah elemen dikurangi, ukuran total ruang di bawahnya tetap tidak berubah.
- 4. cadangan(ukuran_t res_arg=0):untukrangkaianCadangan ruang dan jangan mengubah jumlah elemen yang validmenyimpanparameter kurang dari
- rangkaianKetika ukuran total ruang di bawahnya adalahpencadanganUkuran kapasitas tidak akan diubah.
Struktur berikut ada di 32 Verifikasi di bawah platform, 32 Penunjuk di bawah platform bit menempati 4 byte.vsdown Struktur stringstring menyumbang total 28 byte , struktur internalnya sedikit lebih rumit dulu Ada serikat pekerja, yang digunakan untuk mendefinisikan Ruang penyimpanan string dalam string:
- Jika panjang string kurang dari 16, array karakter tetap internal digunakan untuk menyimpannya.
- Ketika panjang string lebih besar dari atau sama dengan16Kapan, ruang terbuka dari tumpukan
union _Bxty { // storage for small buffer or pointer to larger one value_type _Buf[_BUF_SIZE]; pointer _Ptr; char _Alias[_BUF_SIZE]; // to permit aliasing } _Bx;Desain ini juga masuk akal 16 ,Itu rangkaian Setelah objek dibuat, sudah ada 16 Ruang tetap untuk array karakter, tidak perlu membuatnya melalui heap, dan efisiensi tinggi.Kedua: Dan satu ukuran_t Bidang tersebut menampung panjang senar, a ukuran_t Bidang menyimpan total kapasitas ruang yang dialokasikan di heap.Akhirnya: Tetap saja Ada penunjuk Lakukan sesuatu yang lain.Oleh karena itu, totalnya16+4+4+4=28byte.![]()
Bahasa Indonesia: Bahasa Indonesia: g++ Turun rangkaian StrukturBahasa Inggris Turun, rangkaian Ini diimplementasikan melalui copy-on-write. rangkaian Jumlah total objek 4 Bytes, ini hanya berisi sebuah pointer, yang akan menunjuk ke sepotong ruang heap di masa depan, dan berisi bidang-bidang berikut:
- ukuran ruang keseluruhan
- Panjang tali efektif
- Penghitungan referensi
- Penunjuk ke ruang tumpukan yang digunakan untuk menyimpan string.
struct _Rep_base { size_type _M_length; size_type _M_capacity; _Atomic_word _M_refcount; };
PS: Saat mengimplementasikan sendiri kelas string, Anda harus memperhatikan masalah salinan dangkal.
- //string.h
- #pragma once
- #include<iostream>
- #include<assert.h>
- using namespace std;
- namespace mystr {
- class string
- {
- public:
- //迭代器, 因为字符串底层内存连续, 所以可以简单的定义成指针
- typedef char* iterator;
- typedef const char* const_iterator;
- //配合范围for循环
- iterator begin() { return _str; }
- iterator end() { return _str + _size; }
- //兼容常量字符串
- const_iterator begin() const { return _str; }
- const_iterator end() const { return _str + _size; }
- //string();
- string(const char* str = "");
- string(const string& s);
- string& operator=(string temp) { swap(temp); return *this; }
- ~string() { delete[] _str; _str = nullptr; _size = _capacity = 0; }
- //返回C语言字符数组
- 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 n);
-
- void push_back(char ch) { insert(_size, ch); }
- void append(const char* str) { insert(_size, str); }
-
- string& operator+=(char ch) { insert(_size, ch); return *this; }
- string& operator+=(const char* str) { insert(_size, str); return *this; };
-
- void insert(size_t pos, char ch);
- void insert(size_t pos, const char* str);
- void erase(size_t pos = 0, size_t len = npos);
-
- size_t find(char ch, size_t pos = 0) {
- for (size_t i = pos; i < _size; i++) if (_str[i] == ch) return i;
- return npos;
- }
- size_t find(const char* str, size_t pos = 0) { return strstr(_str + pos, str) - _str; }
-
- void swap(string& s);
- string substr(size_t pos = 0, size_t len = npos);
-
- bool operator<(const string& s) const { return strcmp(_str, s._str) < 0; }
- 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); }
- bool operator==(const string& s) const {return strcmp(_str, s._str) == 0; }
- bool operator!=(const string& s) const { return !(*this == s); }
- void clear() { _str[0] = '0'; _size = 0; }
-
-
- private:
- char* _str;
- size_t _size;
- size_t _capacity;
- //一般static变量的定义要放在类外, 整型是特例
- const static size_t npos = -1;
- };
- void swap(string& s1, string& s2);
- istream& operator>>(istream& ci, string& s);
- ostream& operator<<(ostream& co, string& s);
- }
-
- //string.cpp
- #include "string.h"
- namespace mystr {
- string::string(const char* str):_size(strlen(str)) {
- _str = new char[_size + 1];
- _capacity = _size;
- strcpy(_str, str);
- }
- string::string(const string& s) {
- string temp(s._str);
- swap(temp);
- }
- void string::reserve(size_t n) {
- if (_capacity < n) {
- char* temp = new char[n + 1];
- strcpy(temp, _str);
- delete[] _str;
- _str = temp;
- _capacity = n;
- }
- }
- void string::insert(size_t pos, char ch) {
- assert(pos <= _size);
- if (_size == _capacity) {
- size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
- reserve(newcapacity);
- }
- size_t end = _size + 1;
- while (end > pos) _str[end] = _str[end - 1], --end;
- _str[pos] = ch;
- _size++;
- }
- void 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 = _size + len;
- while (end > pos + len - 1) _str[end] = _str[end - len], --end;
- memcpy(_str + pos, str, len);
- _size += len;
- }
- void string::erase(size_t pos, size_t len) {
- if (len > _size - pos) _str[pos] = '0', _size = pos;
- else strcpy(_str + pos, _str + pos + len), _size -= len;
- }
- void string::swap(string& s) {
- char* temp = _str;
- _str = s._str;
- s._str = temp;
- std::swap(_size, s._size);
- }
- string string::substr(size_t pos, size_t len) {
- if (len > _size - pos) { string sub(_str + pos); return sub; }
- else {
- string sub;
- sub.reserve(len);
- for (size_t i = pos; i < pos + len; i++) sub += _str[i];
- return sub;
- }
- }
- void swap(string& s1, string& s2){ s1.swap(s2); }
- istream& operator>>(istream& ci, string& s) {
- s.clear();
- char ch = ci.get();
- while (ch != ' ' && ch != 'n') s += ch, ch = ci.get();
- return ci;
- }
- ostream& operator<<(ostream& co, string& s) {
- for (size_t i = 0; i < s.size(); i++) co << s[i];
- return co;
- }
- }
- //test.cpp
- #include "string.h"
- namespace mystr {
- void test1() {
- string s1 = "1111";
- string s2 = s1;
- cout << s1.c_str() << endl << s2.c_str() << endl;
- cout << s1.size() << endl;
- }
- void test2() {
- string s1 = "111";
- string s2 = "222222";
- s1 = s2;
- cout << s1.c_str() << endl;
- }
- void test3() {
- string s1 = "111222333";
- for (auto& i : s1) i += 3;
- cout << s1.c_str() << endl;
- const string s2 = "111222333";
- for (auto& i : s2) cout << i;
- cout << endl;
- for (size_t i = 0; i < s1.size(); i++) cout << (s1[i] += 2);
- cout << endl;
- }
- void test4() {
- string s1 = "sadfsf";
- s1.insert(2, '-');
- cout << s1.c_str() << endl;
- s1.insert(0, '-');
- cout << s1.c_str() << endl;
- s1.insert(2, "11111");
- cout << s1.c_str() << endl;
- s1.insert(0, "222222");
- cout << s1.c_str() << endl;
- }
- void test5() {
- string s1 = "asgfidsgf";
- s1.push_back('-');
- cout << s1.c_str() << endl;
- s1.append("=====");
- cout << s1.c_str() << endl;
- s1 += 'w';
- cout << s1.c_str() << endl;
- s1 += "0000";
- cout << s1.c_str() << endl;
- s1.erase(10);
- cout << s1.c_str() << endl;
- s1.erase(7, 100);
- cout << s1.c_str() << endl;
- s1.erase(3, 2);
- cout << s1.c_str() << endl;
- s1.erase(0);
- cout << s1.c_str() << endl;
- }
- void test6() {
- string s1 = "ksjfghks";
- cout << s1.find('h', 2) << endl;
- cout << s1.find("ghk", 2) << endl;
- cout << s1.find("ghksgs", 2) << endl;
- }
- void test7(){
- string s1 = "sggsdsdf";
- string s2 = "sdgfrgdb";
- cout << s1.c_str() << endl;
- cout << s2.c_str() << endl;
- swap(s1, s2);
- cout << s1.c_str() << endl;
- cout << s2.c_str() << endl;
- s1.swap(s2);
- cout << s1.c_str() << endl;
- cout << s2.c_str() << endl;
- string s3 = s1.substr(2, 5);
- cout << s3.c_str() << endl;
- }
- void test8() {
- string s1, s2;
- cin >> s1 >> s2;
- cout << s1 << endl << s2 << endl;
- }
- }
- int main() {
- mystr::test8();
- return 0;
- }