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