C++:String類的使用

? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?創作不易,感謝三連!!?

? ? ? 在C語言中,我們想要存儲字符串的話必須要用字符數組

char str[]="hello world"

? ? ? ?這其實是將在常量區的常量字符串拷貝到數組中,我們會在數組的結尾多開一個空間存儲\0,這樣我們如果想在訪問的時候,比如打印,我們總是認為這個字符串是會讀取到\0結束的

但是過于依賴\0也會有一系列的問題:

1、如果我是一個很長的字符串,但是中間有幾個/0,那么我很難直接打印出來全部的字符串,因為訪問到\0就會卡住

2、如果我們想通過鍵盤輸入hello world,我們把它當成一個字符串,但是cin和scanf會默認訪問到第一個空格或者是換行符就結束。

也就是說,我們的字符串如果有空格,那么還得分批次打印……

3、如果我想減少、增加、修改……這個字符串中的某些字符,也十分麻煩……如果是靜態字符數組,會面臨空間不夠的問題,如果是動態字符數組,那么我們還要時刻注意空間的管理,稍不留神就會越界訪問。

?4、雖然C語言中提供了一系列的str類的庫函數,但是這些庫函數都是以字符串分離開的,沒有把該字符串作為一個整體,并且也容易受到\0的影響。這并不符合C++面向對象的思想。

? ? ? 基于此,我們的祖師爺在想,能不能把string封裝成一個類,把它像順序表一樣管理起來,給他增設一些常用的比如增刪查改的函數接口?針對擴容進行檢查?利用構造函數和析構函數幫助我們管理內存呢??因而我們的string類就誕生了!!

一、標準庫中的string類

想要學習strling類,就要去通過他的文檔去了解

string類的文檔介紹

? ? ? ?誒!!我們發現string類竟然是一個叫做basic_strling的類模版生成的?難道string類還能有其他版本??沒錯!!string類有很多版本

?為什么string要有這么多版本呢??原因是這樣的:

C語言最早都是由老美發明的,他們研究出了ascii碼表

? ? ? ?為什么要發明這個東西呢??因為我們的語言和計算機的語言是不一樣的,計算機只能看得懂二進制的語言,所以我們為了能讓計算機看懂我們的語言,我們必須要給一個映射表,?比如我們想打印apple,那么計算機通過這個ASCII碼表來匹配,比如a對應的是97 p對應的是112 l對應的是108 e對應的是101.我們通過調試轉出10進制是可以驗證這個結果的。

? ? ? 一個字節是8個比特位,所以最多其實可以有256個表示的方法。而美國的英文字母才26個,哪怕算上大寫,算上數字,算上一些符號,128個,也就是7bit就足夠了!!所以ASCII碼在使用英文的國家是非常友好的,每個字節都可以存儲一個字符,這樣就都可以表示出來。

? ? ? 但是老美也想把技術推廣到其他國家啊!!比如中國漢字特別多,如果全部像ASCII碼表一樣都按照一個字節的方式,那漢字遠遠不止256個啊!

? ? ? 隨著計算機的發展,不同國家也出現了很多字符編碼,但是由于字符編碼不同,計算機在不同國家之間的交流變得很困難,經常會出現亂碼的問題,比如:對于同一個二進制數據,不同的編碼會解析出不同的字符

? ? ?當互聯網迅猛發展,地域限制打破之后,人們迫切的希望有一種統一的規則, 對所有國家和地區的字符進行編碼,于是 Unicode 就出現了?

?unicode又有三個版本:

1、UTF-8

?UTF-8: 是一種變長字符編碼,被定義為將碼點編碼為 1 至 4 個字節,具體取決于碼點數值中有效二進制位的數量

UTF-8 的編碼規則:

  1. 對于單字節的符號,字節的第一位設為?0,后面 7 位為這個符號的 Unicode 碼。因此對于英語字母,UTF-8 編碼和 ASCII 碼是相同的, 所以 UTF-8 能兼容 ASCII 編碼,這也是互聯網普遍采用 UTF-8 的原因之一
  2. 對于?n?字節的符號(?n > 1),第一個字節的前?n?位都設為?1,第?n + 1?位設為?0,后面字節的前兩位一律設為?10?。剩下的沒有提及的二進制位,全部為這個符號的 Unicode 碼

?2、UTF-16

UTF-16 也是一種變長字符編碼, 這種編碼方式比較特殊, 它將字符編碼成 2 字節 或者 4 字節

具體的編碼規則如下:

  1. 對于 Unicode 碼小于?0x10000?的字符, 使用?2?個字節存儲,并且是直接存儲 Unicode 碼,不用進行編碼轉換
  2. 對于 Unicode 碼在?0x10000?和?0x10FFFF?之間的字符,使用?4?個字節存儲,這?4?個字節分成前后兩部分,每個部分各兩個字節,其中,前面兩個字節的前?6?位二進制固定為?110110,后面兩個字節的前 6 位二進制固定為?110111, 前后部分各剩余 10 位二進制表示符號的 Unicode 碼 減去?0x10000?的結果
  3. 大于?0x10FFFF?的 Unicode 碼無法用 UTF-16 編碼

?3、UTF-32

? ? ? UTF-32 是固定長度的編碼,始終占用 4 個字節,足以容納所有的 Unicode 字符,所以直接存儲 Unicode 碼即可,不需要任何編碼轉換。雖然浪費了空間,但提高了效率。

? ? ? ?UTF-8、UTF-16、UTF-32 是 Unicode 碼表示成不同的二進制格式的編碼規則,同樣,通過這三種編碼的二進制表示,也能獲得對應的 Unicode 碼,有了字符的 Unicode 碼,按照上面介紹的 UTF-8、UTF-16、UTF-32 的編碼方法 就能轉換成任一種編碼了

? ? 總結:由于UTF-8兼容ASCII,這是他的最大優勢,并且在我們日常編程中很多情況只需要一個字節就可以,雖然字節存儲的時候需要用一些比特位來區分該字符是幾個字節的,但是從效率上來說,他可以根據具體的情況去決定用幾個字節去存儲,所以互聯網大多采用UTF-8,而UTF-16也是變長,他的起點就是兩個字節,兩個字節其實可以表示完大部分國家的字符了,只有極少數古老的文字可能會需要用到4個字節。UTF-32就很粗暴,無論什么都是用4個字節,所以足夠容納所有的Unicode字符,雖然浪費了空間,但是不需要任何的編碼轉換,效率會比較高。但是使用得很少,在C11的時候引入了u32string。

?簡單介紹GBK:

? ? 但是微軟使用的主要還是GBK,Windows支持GBK的時候UTF-8還沒有普及,而微軟是一家及其看重存量客戶和兼容性的公司,形成了路徑依賴不能輕易改變。

? ? ?GBK是大部分用兩個字節表示,一些比較生僻的用三個字節表示

并且一般都是把讀音類似的編在一起

? ? ? 以上只是淺淺了解為什么string有這么多個版本,下面開始研究string類!!

二、string類的接口說明

2.1 string對象常見構造(constructor)

?我們研究幾個比較重要的

1、string()

構造空的string對象,即空字符串

2、string(const char* s)

用C-string來構造string類對象

?其實相當于將常量字符串拷貝到str中

3、string(const string&s)?

拷貝構造函數

?

拷貝構造其實是深拷貝,因為str1和str2指向的是不同的空間

4、string(size_t n, char c)

意思是用幾個相同的字符去構造

5、string (const string& str, size_t pos, size_t len = npos);

意思是,給一個string類,讀取從他的第pos個位置開始往后的len個字符。

如果len給大了,就全部打印完

?我們還注意到len如果不給,會給一個缺省值nops,nops是什么呢?

?我們可以看到npos是string類里面的一個靜態成員變量,他的值是-1,但是由于是size_t類型,所以轉化成無符號整型是一個特別大的數

所以如果我們不傳的話,也是直接拷貝完。跟傳太大是一樣的

?6、string (const char* s, size_t n);

?

?給一個常量字符串,從第一個位置拷貝到第n個位置

總結: 5和6易混淆,第一個傳str類,然后從第pos個位置開始拷貝len個字符,第二個是傳常量字符串,從第一個位置拷貝到n位置。

?2.2?string類對象的容量操作(Capacity)

?1、size和length

size和length其實是一樣的, 都代表字符串的長度,但是早期STL還沒出現的時候,strling類用的是length,但是后來STL出來后,里面大部分都是用的size,所以為了保持一致性又造了一個size出來,平時用哪個都可以的。

?2、capacity

表示string當前的容量,一般來說是默認不算上/0

?這邊其實是16,但是capacity不會吧/0算進去。相當于capacity是實際容量-1

那string類究竟是如何擴容的呢?我們來用一段代碼觀察一下:

?不同編譯器存在差異,因為用的STL版本可能不一樣,我們看看g++

對比后我們可以看到區別:

? ? vs用的是PJ版STL,字符串會先被存在_Bx數組中,超過之后才會去動態開辟空間,第一次擴容是從32開始進行1.5倍擴容。而g++是SGI版STL,直接就是從0開始,然后根據情況直接開始擴容,從0開始進行2倍擴容

3、reverse

作用是提前去增加容量,擴容的效率是很低的,所以如果我們知道這個string類最多需要空間,我們一次性開好,可以減少拷貝。如果是減少的話,不會縮容。

他根據1.5倍的擴容規則,至少會擴容到超過你的要求。如果是g++的話,就是剛好到你要求的

?4、resize

會去改變size,減少的話就是變少(不會改變容量),如果增多的話就可能會擴容順便幫助我們初始化,第一個版本的話初始化補\0,第二個版本的話就是補自己想要初始化的內容

?5、empty

?字符串為空返回1,不為空返回0

6、clear

?清楚字符串,變成空字符串(不會縮容)

7、shrink_to_fit

?意思是縮容到剛好夠容納他的有效字符個數

如上圖一開始的空間是32,然后我們將size變成5,然后進行縮容到剛好夠容納他的大小

?所以前面的resize和reverse如果減少的話,都是不會改變容量大小的!!clear也不會

7、小總結

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不會改變容量大小。

5.縮容的shrink_to_fit盡量不要用,意義不大,而且任何一個接口都不會幫我們縮容

2.3 string類對象的訪問及遍歷操作(Iterators

1、operator[ ] / at
?

訪問下標為pos的字符,at和他是一樣的功能?

?2、begin+end

獲取一個字符的迭代器+獲取最后一個字符的迭代器,要用到iterator(迭代器)

可以把迭代器理解成指針,begin是開始的指針,end是指向\0的指針,注意是左閉右開!!?

如果是用const類型的迭代器,就不能修改?

至此我們知道了三種可以訪問的字符串的方法:?1、下標遍歷 2、迭代器遍歷 3、范圍for

3、rbegin+rend

跟上面差不多,只不過是從尾開始訪問

有沒有感覺string::reverse_iterator有點難寫,那用auto是不是更香

?2.4 string類對象的修改操作(Modifiers)

1、push back

尾插一個字符

2、 string::operator+=?

?3.append

(1) string& append (const string& str);

直接尾插一個str對象

(2)string& append (const string& str, size_t subpos, size_t sublen);

從這個字符串的subpos位置往后的sublen個字符尾插

(3)string& append (const char* s)

尾插一個字符串

(4)string& append (const char* s, size_t n);

尾插字符串中的前n個字符

?(5)string& append (size_t n, char c);

尾插n個字符

?一般來說我們更喜歡用+=,除非是一些特殊情況才會去用append

4,insert?

(1) string& insert (size_t pos, const string& str)和string& insert (size_t pos, const char* s);

從第pos個位置開始插入字符

(2)string& insert (size_t pos, const string& str, size_t subpos, size_t sublen)

是從被插入字符串中的subpos位置往后選len個字符插入

(3)?string& insert (size_t pos, const char* s, size_t n);

是從被插入字符串中選前n個字符插入

(4)string& insert (size_t pos, size_t n, char c);

從第pos個位置開始插入n個相同字符

5.erase?

?從pos位置開始往后刪除len個字符,不穿nops默認就pos后面全刪

一般來說insert和erase都可能設計到大量數據的移動,所以不建議使用!!?

6,pop_back

尾刪一個字符

7,replace

(1)string& replace (size_t pos, size_t len, const string& str)和string& replace (size_t pos, size_t len, const char* s);

將pos位置開始后面的len個字符替換成別的字符串

?(2)string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);

是從被替換字符串中的subpos位置往后選sublen個字符插入

(3)string& replace (size_t pos, size_t len, const char* s, size_t n);

是從被替換字符串中選前n個字符插入

?(4)string& replace (size_t pos, size_t len, size_t n, char c);

替換n個相同字符

8.swap

交換兩個字符串

思考:

明明全局swap也可以達到交換的效果,那string里面也實現一個swap的成員函數有必要嗎???

?

綜上,要盡量使用成員函數的swap?

2.5 string類對象的操作(operations)

1、c_str(重點)

?返回一個指向C類型的字符串指針,下面介紹他的用處:

? ? ?我們可以觀察到,s1.c_str()返回的其實是一個char*指針,但是為什么打印出來的不是地址呢??因為cout可以自動識別類型,對于char*類型的指針他會把它當成是字符串去處理,只要指針不是char*類型的,都會當成打印地址。

? ? ?我們會發現,當我們尾插‘\0’后再插入一些字符,打印出來的結果就不一樣了,因為對于c語言來說,字符串默認是讀取到\0停止,但是對于string來說,讀取多少是取決于他的成員變size!!

如果string類我們想用C語言的方法處理文件,就可以用c_str?

?2、find

?找一個字符里的子串是否存在,如果存在,返回對應的第一個字符的下標,如果不存在,就會返回string::npos。

(1)(3)(4)版本差不多,區別是一個是找string類,一個是找常量字符串,一個是找字符。pos的缺省值0,不傳的話就是從頭開始遍歷往后找,我們也可以通過pos來縮小查找的范圍。

(2)版本就是 找常量字符串從pos位置開始的n個字符

?3、refind

?和find的區別就是默認是pos開始從后往前找

?4.substr

?從pos位置開始截取len個字符返回,不傳len就是默認全部返回(經常和find以及rfind配合使用)

比如我們想打印出.com,我們可以先用find去定位'.'然后再打印

?如果我們不知道幾個字符,s1.size()-pos剛好是剩下所有的字符,或者就干脆不傳,這時候相當于就是把后面的全部打印完

有些時候要從后往前找(rfind)

?如果我們想打印中間怎么辦??比如"http://www.cplusplus.com/reference/string/string/find/"我想打印出www.cplusplus.com

5.find_first_of

?找到第一個匹配的子串中任何一個字符的下標

?練習:將Please, replace the vowels in this sentence by asterisks中的abcdef全部換成*

6,find_last_of

找到最后一個與子字符串任意一個字符匹配的下標。其實可以理解從后往前找第一個

?7,find_first_not_of ? / find_last_not_of

跟前兩個類似,區別就是找第一個不匹配的和找最后一個不匹配的

2.6 string類對象的非成員函數

1,operator+ (string)

盡量少用,因為傳值返回導致深拷貝效率很低

2,relational operators (string)

我們可以通過這些重載的操作符來比較字符串!!?

3,operator>>(string)和operator<< (string)

? ? ? ?值得注意的是,從c的字符串數組到c++的string類,原先讀取字符串是默認讀取到\0,但是封裝乘string類后他有了自己的size,所以會根據size去打印,因此是可以打印出\0的,但是>>還是跟之前的scanf一樣,默認以換行或者是空格作為標識,如果我們想打印出有空格的字符串,是行不通的!!

?因此我們想要流插入有空格的字符串,就得用getline

4.getline

?注意要包含string的頭文件

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/712373.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712373.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712373.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端構建之CERT_HAS_EXPIRED和certificate has expired解決方案

問題 2024年 1 月 22 日&#xff0c;淘寶原鏡像域名&#xff08;registry.npm.taobao.org&#xff09;的 HTTPS 證書正式到期。如果想要繼續使用&#xff0c;需要將 npm 源切換到新的源&#xff08;registry.npmmirror.com&#xff09;&#xff0c;否則會報錯。 報錯信息為&a…

Consul服務注冊與發現 Consul配置步驟

Consul服務注冊與發現 Consul配置步驟 consul下載地址 Install | Consul | HashiCorp Developer 啟動需要在 下載好的文件夾里 用cmd 運行consul agent -dev啟動consul Consul配置 配置pom <!--SpringCloud consul config--> <dependency><groupId>org…

【leetcode】回文子串 動態規劃

/*** param {string} s* return {number}*/ var countSubstrings function(s) {let dpnew Array(s.length).fill().map(()>new Array(s.length).fill(false));let num0;for(let i0;i<s.length;i){for(let j0;j<i;j){//在首尾相等時&#xff0c;如果長度時1或者2&…

C++筆記(三)--- 函數重載

目錄 子類繼承父類重載 類成員函數重載 繼承和組合的三種方式請看我上一篇文章 C筆記&#xff08;二&#xff09;--- 繼承和組合-CSDN博客 子類繼承父類重載 當子類繼承父類之后&#xff0c;子類重新定義了一個和父類完全相同函數名稱的函數時&#xff0c;會將父類所有相同…

Pegasus智能家居套件樣例開發--軟定時器

樣例簡介 此樣例將演示如何在Pegasus Wi-Fi IoT智能家居套件上使用cmsis 2.0 接口進行定時器開發。 工程版本 系統版本/API版本&#xff1a;OpenHarmony 3.0 releaseIDE版本&#xff1a;DevEco Device Tool Release 3.0.0.401 快速上手 準備硬件環境 預裝windows系統的PC…

『大模型筆記』RAG應用的12種調優策略指南

RAG應用的12種調優策略指南 文章目錄 一. 概要二. 數據索引2.1. 數據清洗2.2. 分塊2.3. 嵌入模型2.4. 元數據(或未向量化的數據)2.5. 多索引2.6. 索引算法三. 推理階段(檢索和生成)3.1. 檢索參數3.2. 高級檢索策略3.3. 重新排序模型3.5. 大語言模型(LLM)

26、Qt調用.py文件中的函數

一、開發環境 Qt5.12.0 Python3.7.8 64bit 二、使用 新建一個Qt項目&#xff0c;右擊項目名稱&#xff0c;選擇“添加庫” 選擇“外部庫”&#xff0c;點擊“下一步” 點擊“瀏覽”&#xff0c;選擇Python安裝目錄下的libs文件夾中的“python37.lib”文件&#xff0c;點擊“下…

退休開便利店真的靠譜嗎?2024比較賺錢的創業項目排行

近日多個退休后開便利店賺錢的新聞登上熱搜&#xff0c;但是&#xff0c;小編對此有疑問&#xff0c;退休的老年人開便利店真的是一個好選擇嗎&#xff1f; 第一、便利店最基本的轉讓費&#xff0c;裝修費&#xff0c;進貨等等&#xff0c;這筆開支非常大&#xff0c;足以掏空老…

H5下拉刷新分頁

對于分頁需求&#xff0c;分頁數據的請求觸發十分重要&#xff0c;監聽滑動到底的觸發也有很多種。 1.IntersectionObserver監聽 IntersectionObserver 接口&#xff08;從屬于 Intersection Observer API&#xff09;提供了一種異步觀察目標元素與其祖先元素或頂級文檔視口&a…

終結數據混亂!開發者必學的GraphQL秘籍,高效API只需一步

在數字世界中&#xff0c;API就如同城市中的道路&#xff0c;連接著各種服務和數據。然而&#xff0c;傳統的API&#xff08;如RESTful&#xff09;雖然功不可沒&#xff0c;但隨著技術復雜性和需求多樣性不斷攀升&#xff0c;它們顯露出的局限性也呼喚著新的可能出現。此時&am…

Unity中,activeInHierarchy 和 activeSelf

activeInHierarchy&#xff1a; activeInHierarchy 屬性表示游戲對象是否在場景中處于激活狀態&#xff0c;并且是否在層次結構中的激活狀態。它考慮了游戲對象以及其所有父對象的激活狀態。如果 activeInHierarchy 為 true&#xff0c;表示該對象在場景中處于激活狀態且其所有…

LaMa Image Inpainting 圖像修復 Onnx Demo

目錄 介紹 效果 模型信息 項目 代碼 下載 LaMa Image Inpainting 圖像修復 Onnx Demo 介紹 gihub地址&#xff1a;https://github.com/advimman/lama &#x1f999; LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WAC…

《PyTorch深度學習實踐》第十三講RNN進階

一、 雙向循環神經網絡&#xff08;Bidirectional Recurrent Neural Network&#xff0c;BiRNN&#xff09;是一種常見的循環神經網絡結構。與傳統的循環神經網絡只考慮歷史時刻的信息不同&#xff0c;雙向循環神經網絡不僅考慮歷史時刻的信息&#xff0c;還考慮未來時刻的信息…

wireshark過濾和tcpdump抓包指令

Wireshark 過濾器的表達式&#xff0c;用于過濾源 IP 地址為 10.184.148.247 并且目標 TCP 端口為 1883 的數據包。啟用抓包后過濾 ip.addr 10.184.148.247 && tcp.port 1883 主機位10.184.148.19和目標端口為 8080 的操作目標 抓包前過濾 host 10.184.148.19 &…

軟件說明書怎么寫?終于有人一次性說清楚了!

每次寫軟件說明書&#xff0c;你是不是總是毫無頭緒&#xff0c;不知道從何下手&#xff1f;到各網站找資料&#xff0c;不僅格式不規范&#xff0c;甚至可能遺漏關鍵內容&#xff01;挨一頓批不說&#xff0c;還浪費大把時間。別著急&#xff0c;編寫軟件說明書&#xff0c;關…

PostgreSQL開發與實戰(2)常用命令

作者&#xff1a;太陽 1、連庫相關 #連庫 $ psql -h <hostname or ip> -p <端口> [數據庫名稱] [用戶名稱] #連庫并執行命令 $ psql -h <hostname or ip> -p <端口> -d [數據庫名稱] -U <用戶名> -c "運行一個命令;"備注&#xff1…

從理論到落地,大模型評測體系綜合指南

1956年夏&#xff0c;“人工智能” 這一概念被提出。距今已有近70年的發展歷史。中國科學院將其劃分為六個階段&#xff1a;起步發展期&#xff08;1956年—1960s&#xff09;&#xff0c;反思發展期&#xff08;1960s-1970s&#xff09;,應用發展期&#xff08;1970s-1980s),低…

SpringBoot集成Activiti案例

前言 Activiti項目是一項新的基于Apache許可的開源BPM平臺&#xff0c;從基礎開始構建&#xff0c;旨在提供支持新的BPMN 2.0標準&#xff0c;包括支持對象管理組&#xff08;OMG&#xff09;&#xff0c;面對新技術的機遇&#xff0c;諸如互操作性和云架構&#xff0c;提供技…

3.1log | 62.不同路徑,63. 不同路徑 II,343. 整數拆分,96.不同的二叉搜索樹

62.不同路徑 class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m,vector<int>(n,0));for(int i0;i<n;i) dp[0][i]1;for(int i0;i<m;i) dp[i][0]1;for(int i1;i<m;i){for(int j1;j<n;j){dp[i][j]dp[i][j-1]dp[i-…

c++八股文:c++編譯與內存管理

文章目錄 1. c內存管理2. 堆與棧3.變量定義與生命周期4.內存對齊5.內存泄露6.智能指針7.new 和 malloc 有什么區別8.delete和free的區別9.什么野指針&#xff0c;怎么產生的&#xff0c;如何避免野指針10.野指針和指針懸浮的區別11.字符串操作函數參考 1. c內存管理 c在運行程…