C語(yǔ)言中字符串的兩種定義方式詳解
我們知道C語(yǔ)言中是沒(méi)有字符串這種數(shù)據(jù)類型的,我們只能依靠數(shù)組進(jìn)行存儲(chǔ),即字符數(shù)組,而我們定義并且初始化數(shù)組有兩種方式。下面將給大家介紹這兩種方式并且介紹這兩種方式的區(qū)別:
方式1
前兩種是正確的定義方式,第一種之所以沒(méi)有指定字符數(shù)組長(zhǎng)度的原因是編譯器能夠自己推斷出其長(zhǎng)度,無(wú)需程序員自己設(shè)定,這也是我們比較推薦的一種定義方式,但注意內(nèi)存長(zhǎng)度編譯器一經(jīng)判定就無(wú)法再次更改,接下來(lái)我們分析一下第三種編譯器為什么會(huì)出現(xiàn)亂碼。
相信大家都知道,字符串是以'\0'字符為結(jié)束標(biāo)志的,這個(gè)標(biāo)志本身也占用一個(gè)內(nèi)存,我們?cè)谳敵龅臅r(shí)候是看不到這個(gè)字符的,這是由編譯器所決定的,因?yàn)榫幾g器的符本身占用了一個(gè)字節(jié),所以sizeof()這個(gè)關(guān)鍵字在計(jì)算數(shù)組所占內(nèi)存時(shí)要比字符多一個(gè),如圖中的arr1和arr2,而在計(jì)算arr3時(shí),結(jié)果只有5,但輸出和圖二中我們所看到的卻不止5個(gè)字符,那么這是為什么呢?
今天想給大家樹(shù)立一個(gè)概念,我們?cè)诙x一個(gè)變量時(shí),前面的類型加變量名實(shí)際上這是在內(nèi)存中開(kāi)辟了一個(gè)空間,變量所占內(nèi)存的大小不是由變量的值所決定的,而時(shí)由我們最初開(kāi)辟的空間的大小所決定的。這是一個(gè)很容易被大家忽視的一個(gè)小小的概念,希望大家能夠牢記這一概念。
int a = 0;//在內(nèi)存中開(kāi)辟了一段4個(gè)字節(jié)的空間,然后將0的二進(jìn)制補(bǔ)碼形式(0的補(bǔ)碼是其本身)放入到這段內(nèi)存空間中 char b = 'c';//在內(nèi)存中開(kāi)辟了一段一個(gè)字節(jié)的空間,然后將字符'c'所對(duì)應(yīng)的ascii碼值所對(duì)應(yīng)的二進(jìn)制補(bǔ)碼形式放入到這段內(nèi)存空間中 //至于數(shù)組形式實(shí)際和這個(gè)是類似的,就是先開(kāi)辟好數(shù)組所占的內(nèi)存,然后將所要存儲(chǔ)的數(shù)據(jù)的二進(jìn)制補(bǔ)碼形式放入到內(nèi)存空間中
相信大家對(duì)上述原因已經(jīng)有了屬于自己的一些了解,接下來(lái)跟大家談一下為什么數(shù)組arr3會(huì)輸出亂碼,'\0'是字符串的結(jié)束標(biāo)志,但這個(gè)結(jié)束標(biāo)志究竟有什么用呢?用處有兩點(diǎn),第一點(diǎn)是strlen函數(shù)在計(jì)算字符串所占內(nèi)存空間時(shí),遇到'\0'就會(huì)停止,進(jìn)而能夠求得字符串的長(zhǎng)度(當(dāng)然,這個(gè)計(jì)算不會(huì)把'\0'結(jié)束標(biāo)志計(jì)算在內(nèi));第二點(diǎn)是編譯器在執(zhí)行printf函數(shù)時(shí),以字符串形式進(jìn)行輸出字符數(shù)組時(shí),遇到'\0'編譯器就會(huì)停止輸出,在arr3中,我們開(kāi)辟的內(nèi)存空間中放滿了字符,沒(méi)有字符串結(jié)束標(biāo)志'\0',所以編譯器會(huì)在把內(nèi)存空間中的字符輸出完并不會(huì)停止,還會(huì)繼續(xù)進(jìn)行輸出,直到出現(xiàn)'\0'為止。
sizeof()計(jì)算的是變量所占的內(nèi)存空間的大小,即紅色框內(nèi)的內(nèi)存大小,也就是我們定義的大小,而strlen()計(jì)算的是從變量?jī)?nèi)存起始位置開(kāi)始,一直向后進(jìn)行計(jì)算,直到遇到結(jié)束標(biāo)志'\0'為止,即上圖中紅色的框,下面給大家代碼展示一下。
相信大家已經(jīng)有所了解,這也能夠方便我們更好的理解第二種定義方式所遇到的問(wèn)題。
方式2
上述三種定義方式中1和3是正確的,方式2中并未把結(jié)束標(biāo)志'\0'放入到數(shù)組最后一個(gè)空間中,這也是我們常犯的一個(gè)錯(cuò)誤,希望大家要牢記,在采用這種方式對(duì)字符串進(jìn)行定義時(shí),不要忘記加上字符串的結(jié)束標(biāo)志'\0',因?yàn)榫幾g器不會(huì)為程序員自動(dòng)添加'\0',所以我們并不推薦這種方式來(lái)對(duì)字符串進(jìn)行定義,除了加上'\0'之外,另一種方式就是限定字符串長(zhǎng)度,限定之后編譯器會(huì)在末尾加上結(jié)束標(biāo)志'\0'(此處只是指的vs2019編譯器,其它編譯器筆者并未驗(yàn)證),當(dāng)然,最推薦的還是程序員手動(dòng)添加'\0'作為結(jié)束標(biāo)志。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++設(shè)計(jì)模式編程中簡(jiǎn)單工廠與工廠方法模式的實(shí)例對(duì)比
這篇文章主要介紹了C++設(shè)計(jì)模式編程中簡(jiǎn)單工廠與工廠方法模式的實(shí)例對(duì)比,文中最后對(duì)兩種模式的優(yōu)缺點(diǎn)總結(jié)也比較詳細(xì),需要的朋友可以參考下2016-03-03C++中vector容器的注意事項(xiàng)總結(jié)
在c++中,vector是一個(gè)十分有用的容器,下面這篇文章主要給大家介紹了關(guān)于C++中vector容器的注意事項(xiàng),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12