char * 与char []区别总结
1.先上結(jié)論
c++代碼里頭經(jīng)常見到char * 與char []的寫法,這兩種寫法都可以表示一個(gè)字符串。比如:
void charcode() {char* a = "c1";char b[] = "c2";printf("a=%s, b=%s", a, b); }上面這段代碼,最后輸出的結(jié)果為
a=c1, b=c2所以這兩種方式都可以表示字符串,那么區(qū)別到底是什么?我們先說結(jié)論,后面再來分析:
char * 這種方式表示常量指針,char[] 這種表示指針常量!
2.char *的方式
我們看看char* a =“c1” 這行代碼到底執(zhí)行了哪些操作:
1.聲明了一個(gè)char*的標(biāo)量,也就是聲明了一個(gè)指向char的指針。
2.在內(nèi)存的文字常量區(qū),開辟了一個(gè)空間存儲(chǔ)字符串常量"c1"。
3.返回這個(gè)區(qū)域的地址,并且這個(gè)地址作為值給了字符指針變量a。
最終的結(jié)果就是:指針變量a指向了一個(gè)字符串常量"c1"。
因?yàn)椤眂1“是在常量區(qū),所以其內(nèi)容是不可以修改的。如果我們?cè)噲D修改a指向的內(nèi)存區(qū)域值,程序會(huì)崩潰
void charcode() {char* a = "c1";*(a+1) = '2';cout<<a<<endl; }此時(shí)代碼會(huì)報(bào)錯(cuò)崩潰
/bin/sh: line 1: 48910 Bus error: 10 .......但是a是個(gè)指針變量,其指向的地址是可以修改的,因此如下代碼可以正常運(yùn)行
void charcode() {char* a = "c1";a = "c2";printf("a=%s", a); }輸出為:
a=c23.char[] 的方式
下面我們?cè)賮砜纯碿har[]的方式
說起char[],得從C語言說起。string本質(zhì)上是個(gè)類,而C語言是面向過程的編程方式,里面沒有class,因此C語言中的string其實(shí)是個(gè)字符數(shù)組,也就是char[]。例如
char str[6] = {"hello"}; cout<<str<<endl; cout<<strlen(str)<<endl; cout<<sizeof(str)<<endl;上面定義了一個(gè)有6個(gè)元素的數(shù)組,元素類型為字符char,存儲(chǔ)的字符為"h e l l o \0"。加上\0的目標(biāo),是代表空格符,在字符串末尾加上"\0”, 表示字符串結(jié)束,堵到這個(gè)位置就會(huì)停下來,不然會(huì)一直讀下去。
上面的代碼輸出為
hello 5 6其中,strlen是去掉"\0"以外的長(zhǎng)度,sizeof則包括"\0"。
為什么cout <<str能讀取到字符串hello?
因?yàn)樵贑語言中規(guī)定,數(shù)組名就代表數(shù)組所在內(nèi)存位置的首地址,也就是str[0]的地址,即str=&str[0],因此讀取str的時(shí)候其實(shí)就是在訪問hello中h的地址。
C語言中操作字符串是通過它在內(nèi)存中的存儲(chǔ)單元的首地址進(jìn)行的,這是字符串的本質(zhì)。
char str[6] = {"hello"};這行代碼實(shí)現(xiàn)了2個(gè)操作:
1.聲明了一個(gè)char類型的數(shù)組str。
2.給str數(shù)組賦值,即將"hello"中的每一個(gè)字符分別賦值給數(shù)組中的每一個(gè)元素并存儲(chǔ)在棧上,數(shù)組位置不夠的字符以"\0"填充。
結(jié)合上面的分析,我們不難發(fā)現(xiàn):
1.str指向的數(shù)組地址是不能發(fā)生變化的。比如我們?nèi)绻@么操作
第二行在IDE里會(huì)報(bào)錯(cuò)并提示:表達(dá)式必須是可修改的左值。
但是,對(duì)應(yīng)的數(shù)組里面的內(nèi)容是可以修改的:
void charcode() {char str[6] = {"hello"};str[0] = 'H';cout<<str<<endl; }上述代碼就可以正常運(yùn)行,并輸出結(jié)果為"Hello"。
4.char *更嚴(yán)謹(jǐn)?shù)膶懛?/h2>
事實(shí)上,char *p = "hello"; 這種寫法是不嚴(yán)謹(jǐn)?shù)?#xff0c;比如在IDE運(yùn)行的時(shí)候,會(huì)報(bào)如下的warning信息:
conversion from string literal to 'char *' is deprecated [-Wc++11-compat-deprecated-writable-strings]char *p = "hello";^ 1 warning generated.原因也很好理解:因?yàn)?p指向的是一個(gè)常量,一旦strcpy(p,”world”)就壞了,此時(shí)會(huì)視圖往只讀區(qū)寫入一個(gè)新值,程序就會(huì)崩潰!所以我們應(yīng)該還是按照類型相同賦值的原則來寫:
const char *p = "hello";這樣就不會(huì)出現(xiàn)問題。
5.小結(jié)
1.char *p = "hello",p指針指向的值是可以變化的,但是p只能指向(字符串)常量,并且其指向的內(nèi)存范圍里內(nèi)容不能發(fā)生改變。規(guī)范寫法為const char *p或者char const *p,p為一個(gè)常量指針。
2.char a[]這種寫法,a的內(nèi)存地址即指向不能變,但是內(nèi)存里的內(nèi)容能發(fā)生變化,等同于char *const a,為一個(gè)指針常量。
3.const在*前:表示const修飾的為所申明的類型,為常量指針
4.const在*后:表示const修飾的為指針,為指針常量
總結(jié)
以上是生活随笔為你收集整理的char * 与char []区别总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LaTeX系统找不到指定文件解决方案
- 下一篇: SwiftUI - @Binding