char* s1 = "hello";//字符串常量
s是一個保存了字符串首地址的指針變量,同時也是字符串的名字,s的內容是第一個字符的地址,當s指向常量字符串時候,內容不能改變(s[1]='y';錯的!因為s[1]就是第二個常量字符的地址,這個地址是唯一的,不能改變!),但是整體可以修改(s = "addd"就可以)。
cout << s1 ;// "hello" cout << *s1; //'h' cout << s[0]; // 'h' cout << *(s1+1); // 'e'
char 2s[] = "goodbye";//字符數組
char s2[]是有連續內存的數組,每個元素是char類型;s2指向的內存區域的地址和容量在生命期里不會改變,但數組里存的內容可以改變。
13 //s2操作同s1類似 14 s2 = s1;//錯誤!!!數組不能用等號賦值(除了初始化) 15 s1 = s2;//對
兩者在內存里都在末位存了‘\0’
作為形參完全相同:
void function(char* s1); void function(char s1[]);
為什么改變s1危險?
hello字符串是在編譯時候就確定了,所以編譯器知道它指的是常量,而且不希望你改變;但是數組只是個存儲工具,編譯時不知道它里面是什么,所以可以改。
int a=0; //全局初始化區 char *p1; //全局未初始化區 main() { int b; //棧 char s[]="abc"; //棧 char *p2; //棧 char *p3="123456"; //123456\0在常量區,p3在棧上。 static int c=0; //全局(靜態)初始化區 p2 = (char*)malloc(20); //分配得來得10和20字節的區域就在堆區。 strcpy(p1,"123456"); //123456\0放在常量區,編譯器可能會將它與p3所向"123456"優化成一個地方。 }
獲取字符串長度
sizeof
當參數是數組名時,返回的時候數組內元素的個數,包括'\0';
當時其他變量時候,返回的是變量所占的字節數;
char *str1="absde"; char str2[]="absde"; int len1 = sizeof(str1);//4,因為str1是字符指針變量,占4個字節 int len2 = sizeof(str2);//6,str2是字符數組名,當sizeof參數是數組名時,返回數組長度(包括'\0')=6
所以求字符串常量的長度,使用strlen;求字符數組的長度,使用sizeof,strlen都可以。
strlen
參數必須是字符型指針,當數組名作為參數傳入時,實際上數組就退化成指針了。
返回字符串的長度,而strlen不區分是數組還是指針,就讀到\0為止返回長度。而且strlen是不把\0計入字符串的長度的。
char *str1="absde"; char str2[]="absde"; int len1 = strlen(str1);//5,strlen不包含'\0' int len2 = strlen(str2);//5,strlen不包含'\0'
