天天看點

把《c++ primer》讀薄(3-1 标準庫string類型初探)

督促讀書,總結精華,提煉筆記,抛磚引玉,有不合适的地方,歡迎留言指正。

問題1:養成一個好習慣,在頭檔案中隻定義确實需要的東西

問題2:c++定義了一個内容豐富的抽象資料類型的标準庫,最重要的兩個标準庫類型是string和vector

因為他們是c++基本内置類型基礎上改進而來,故重要!前者支援變長字元串,後者可以儲存一組指定類型的對象。

問題3:什麼時候會調用預設的構造函數?

預設構造函數,是不帶參數的,可以為所有形參提供預設實參。且它是系統預設提供的,在定義類對象的時候,沒有提供初始化時會自動調用。

問題4:初始化string對象的三個方式:

預設構造函數初始化

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

string對象初始化和字元串字面值常量初始化

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

問題5:cin讀取string的特點

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

注意:程式開頭要包含頭檔案和using聲明

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

問題6:如果想讀取空白字元,那麼不能用輸入流,而是需要使用getline()函數

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

注意:因為getline函數以換行為結束,且是忽略換行!那麼依然要使用endl換行,之是以遇到換行就結束輸入,是因為getline()是用來讀取一整行内容的函數。

問題7:比較string的cin輸入和getline輸入方式

cin适合讀取一個單詞,getline函數适合讀取一行文本,如:

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

小結:當遇到需要每次讀入一個單詞的要求,則使用cin+循環,如果是每次需要讀取一行内容,則使用getline()函數+循環。且還有一個問題,如果使用cin讀取string對象,那麼我們知道開頭或者中間的任何空白都被忽略,且後續遇到空白字元,就終止讀取,但是此時,空白字元還是留在了輸入流内!而getline恰恰相反,不會忽略開頭的空白字元,遇到換行符就結束讀取!但是會丢棄換行符,不會保留在輸入流内!更不會存到string對象裡!

問題8:再論,為何不建議偷懶的直接使用using namespace xxx;俗稱using訓示,而建議使用using聲明?

就怕習慣了,在大型程式裡,經常使用不同的多個庫,如用using訓示,就會包含全部庫的名字空間,有可能出現命名沖突。标準庫std雖然不會,但是專家建議别怕麻煩。

問題9:字元串字面值常量和string類型不是同一個類型!

目的是相容c語言而規定,不要混淆兩者。注意區分!

問題10:string對象的求長度操作

求長度,指的是string對象中字元的個數

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

注意:basic_string<>有雙重身份,一是代替傳統的c字元串,是以應該針對c中的strlen給出相應的函數length()。另一個身份是可以用作stl容器,是以要按照stl容器的慣例給出size(),兩者功能一樣。

問題11:為什麼不建議把size()函數的傳回值指派給c/c++基本内置類型int or其他整型?

string類的size()成員函數傳回的不是整型,而是string::size_type類型,這樣的類型叫庫類型的配套類型,目的是實作機器無關性!因為不同機器的int類型或者無符号int的大小不一樣!平台換了,則一樣的程式可能出現類型的長度溢出錯誤

注意:size_type功能上和 無符号的 int或者 無符号的 long int一樣大小,但是隻是功能一樣!千萬不要随便的指派給int類型,他們不是一個類型!針對不同平台,不同存儲的string對象,傳回的大小極有可能和内置類型的範圍不一樣!引起溢出錯誤!

且顯式的使用傳回值時,應該加上string::size_type,來說明這個類型是string類定義的

看下對應的彙編源碼:

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

發現内部實作機制确實是這樣調用的:std::basic_string<char,std::char_traits<char>,std::allocator<char> >::size ()

問題12:string對象判空操作

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

問題13:string對象的關系操作(串比較),使用運算符重載,實作比較對象的功能!傳回bool類型

1、string對象比較操作,區分大小寫!比如

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

2、判等或不等,要比較兩點,一是長度,二是内容

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

而下面就不是相等的

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

問題14:string對象的關系比較比的誰大,誰小的依據是什麼?

比較原理是字典排序的原理

1、如果s1和s2長度不一樣,且短的整體和長的前面某連續的部分比對,那麼比較長度,判斷結果

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

再看

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

2、如果s1和s2長度不一樣,且短的整體和長的前面部分沒有比對,那麼隻需比較第一個不比對的字元來做判斷

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

即使str1長度比str2大,此時此景,比較和長度無關

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

3、如果s1和s2長度一樣,那就直接看s1和s2的字元比對否,比對就是相等,不比對就比較第一個不比對的字元,來判斷大小

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

對于有大寫,有小寫,或者數字的情況,是依據ascii碼,大寫字母碼值比0-9的數字小,數字又比小寫字母小(也就是大寫字母在最前面,其次是數字,然後小寫最後面),也就是任何大寫字母的string對象和小寫比較,都是小于關系!

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

問題15:string對象的指派操作

把一個string對象指派給另一個string對象

string串對象指派操作的底層實作機制

1、先把str1占有的記憶體釋放

2、配置設定給str1滿足存放str2副本的記憶體空間

3、把str2所有字元複制到str1的新記憶體空間内

這樣的繁瑣操作,導緻大部分的string庫類型的指派操作效率比較低!

問題16:string串對象的連接配接操作,使用運算符重載的+和+=号

連接配接string對象

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

連接配接string對象和字元串字面值常量

注意,這樣混合連接配接,必須保證+操作符的兩邊至少有一個操作數是string對象!

這樣沒問題,因為前面+之後是string對象類型,後面+\n也是ok的。比如如下就是錯誤的:

問題17:string串對象下标操作的陷阱

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

上面的寫法,嚴格來說,是錯的!即使運作對,因為前面說過,這樣失去了c++設計庫類型跨平台的初衷!容易溢出錯誤!改為:

因為size函數傳回類型不是整型!在計算下标值的時候,最好不要用内置整型類型!且不要越界!範圍是0~(length-1),類似c和c++的數組下标範圍。因為c++标準庫對索引的範圍不作檢測!這就需要程式員手動注意!

問題18:string對象對字元的處理操作

不僅針對string的字元,對其他char類型也适用。這些操作定義在頭檔案cctype.h中,數量很多:

測試是否為數字或者字母

很好了解,is一般是判斷函數的字首名稱,num=number代表判斷數字0-9,al=alphabet代表判斷字母表的字母

測試數字,是就傳回ture

測試字母,是就傳回true

測試小寫字母,是就傳回true

測試标點符号

測試空白字元

測試大寫字母

測試16進制數

大寫、小寫轉換

大寫a的ascii值為65,小寫a為97,大寫排在小寫前面,碼值嬌小

測試是否是可列印字元

可以列印的字元,比如:數字0-9,字母a-z,a-z,空白字元是空格 ,回車,水準和垂直制表,換行,進紙符,标點符号是除了字母,數字或者可列印空白字元以外的其他可列印字元。

測試是否為空格,如果不是空格但是可以列印,傳回ture,否則false

測試是否為控制字元,control縮寫cntrl

控制字元(control character),出現于特定的資訊文本中,表示某一控制功能的字元。

在ascⅡ碼中,第0~31号及第127号(共33個)是控制字元或通訊專用字元,如控制符:lf(換行)、cr(回車)、ff(換頁)、del(删除)、bs(倒退)、bel(振鈴)等;通訊專用字元:soh(文頭)、eot(文尾)、ack(确認)等。

問題19:c版本的頭檔案在c++的寫法

cctype頭檔案就是c的type.h頭檔案,即c++的c版本頭檔案,不要寫.h,而是前面加c。且cname頭檔案都定義在了命名空間std内部,而.h檔案沒有這樣定義!

建議使用cname形式的頭檔案,在c++裡。即使他們的内容是一樣的!這樣做的目的是為了和标準庫std保持一緻!

問題20:計算給定string字元串的标點符号個數

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

漢字不是用ascii表示的,漢字有其單獨的編碼。gb2312,gbk……一個漢字是有兩個位元組組成,具體參見:gb2312-80,ascii碼表針對的是西洋文字。

問題21:判斷下面程式合法性

報錯,程式發生中斷,看似是輸出string字元串對象的第一個字元,但是發現,s是一個空字元串,長度=0,故s[0]不管用!在vs2010中編譯出錯,程式中斷。

問題22:從string字元串中去掉标點,要求如果輸入字元串包含标點,輸出則是去掉标點的字元串

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

如果沒有标點

把《c++ primer》讀薄(3-1 标準庫string類型初探)

發現,c++在處理字元串問題上,比c要友善。

問題23:讀取多個string對象,把他們連接配接為新串,然後把組成新串的字元串對象用空格隔開

把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)
把《c++ primer》讀薄(3-1 标準庫string類型初探)

辛苦的勞動,轉載請注明出處,謝謝……

http://www.cnblogs.com/kubixuesheng/p/4119776.html

繼續閱讀