1、以字符串形式出現的,編譯器會在結尾自動添加\0,思考,爲什麼?
存在的C語言方法,如strlen(s),計算字符串的長度,其中s指針。strlen要計算字符串長度,必須知道哪裏是結尾,因此使用\0表示結尾。只有字符數組纔有\0的概念,其它類型(int)的數組沒有這個概念。因爲其他類型的數組或者指針,沒有strlen這種方法。
那麼問題來了,int數組如何計算長度呢?如int a1 = {3,7,9,};
使用sizeof(a1)/sizeof(int)。
2、數組可以在棧上分配,也可以在堆上分配,但必須指定大小。
char a1[100]; //在棧上分配
char* pa = new char[100];// 在堆上分配,返回首元素的地址
3、char a1[] = "abc"; 相當於在棧頂分配4個字節,分別放上a,b,c,\0,等價於char a1 ={'a','b','c','\0'};
4、char* pa = "abc"; 分析一下就知道,pa是char指針,"abc"是一個文本字符串,顯然類型不吻合,需要適配。可認爲編譯器做了下面的事情:在常量區分配4個字節,分別放上a,b,c,\0,然後把a的地址返回給pa。
注意:文本字符串放在常量區,是不可修改的,試圖修改,運行異常。那麼在思考一下,既然右邊是const,而pa並沒有限定爲const char*,按道理賦值失敗。爲什麼可以成功?
可以認爲在C語言中,到處充斥着這樣的代碼。爲了兼容,必須允許。但是,我們應該寫const char* pa ="abc"; 這樣的話,試圖修改pa的內容,編譯報錯。
5、char a1[] = "abc", 等價於char a1[] = {'a','b','c','\0',}; strlen(a1)等於3,長度不包括\0
假如這樣寫 char a1[] = {'a','b','c',}; strlen(a1)是多少? 答案不確定,因爲strlen一直找到\0才認爲是結尾。
6、 char a1[] = "abc"; 下面的結果分別是什麼?
cout<<&a1[0]<<endl;
cout<<a1<<endl;
輸出相同,都是數組元素的第一個地址。
7、char* pa = "abc"; 下面的結果分別是什麼?
cout<<&pa<<endl;
cout<<&pa[0]<<endl;
cout<<pa<<endl;
第一行輸出pa在棧上的地址,第二行和第三行輸出相同,都是首地址。pa是指針,就是指向首個元素的地址。
8、char a1[5]; 數組名是個指針常量,不能修改指向。
9、char* pa = "abc"; 可認爲pa是個指向常量的指針。
10、下面的結果,違反直覺,按道理第4行,第5行應該輸出地址。但是卻輸出指向的字符串。這有一定的合理性,我們打印char指針,往往是要看指向的內容,而不是要看地址是多少。而且cout很容易做到,只要遇到\0就結束。那麼問題來了,我想看地址怎麼辦?使用int強制轉化爲地址。
1 char a1[]="abc";
2 char* pa="def";
3
4 cout<<a1<<endl; //輸出abc
5 cout<<pa<<endl; //輸出def
6
7 cout<<(int)a1<<endl; // 輸出a1地址
8 cout<<(int)pa<<endl; // 輸出pa地址
11、
1 char p[]="abcde";
2 char* p2="abcde";
3
4 cout<<sizeof(p)<<endl; //數組大小爲6
5 cout<<sizeof(p2)<<endl; // 指針大小爲4
6
7 cout<<strlen(p)<<endl; // 長度爲5
8 cout<<strlen(p2)<<endl; // 長度爲5
轉載請註明本文地址:char數組與char指針