先聲明,,這是摘抄的,,為了得浏覽量所以改為是原創的,,原地址為原址
1.聲明字符數組時,[]中的數應為數組中字符個數,包括'/0'
如 char p[5] = "dddd";
則實際為:'d' 'd' 'd' 'd' '/0'.
若 char p[5] = "ddddd";
則編譯出錯,提示越界.
2.(1)初始化字符數組時,會自動補充'/0'
如 char p[5] = "dd";
則實際為:'d' 'd' '/0' '/0' '/0'
再如 char p[3] = "";
則實際為:'/0' '/0' '/0'
(2)若沒有只是聲明字符數組,沒初始化並不會自動補'/0'
如 char p[3];
則實際字符數組內容並不可知,因為實際上p也是個指針,現在並不知道它的指向
(3)同理,聲明字符指針並不初始化時,也不知道指針的指向
如 char *p;
(4)聲明並初始化指針,由於"內存對齊"(由編譯器實現),對32位機
則會補齊4位,自動補'/0'
如 char *p = "a";
則實際為:p[0]='a',p[1]='/0',p[2]='/0',p[3]='/0'.
若 char *p ="";
則實際為:p[0]='/0',p[1]='/0',p[2]='/0',p[3]='/0'.
3.strlen(const char* p)函數返回的是字符數組中字符個數,不包括'/0'
如 char p[5] = "dddd";
char p2[3] = "";
int i = strlen(p);
int j = strlen(p2);
此時 i = 4 , j = 0
4.關於strcpy函數
函數的實現為:
char *strcpy(char *strDestination, const char *strSource)
{
assert(strDestination && strSource);
char *strD=strDestination;
while ((*strDestination++=*strSource++)!='/0')
NULL;
return strD;
}
這個函數並不會檢查是否下標越界,所以使用時要注意:
->給函數傳的第一個參數必須是字符數組或者是已經指向字符數組的字符指針.
->並且第一個參數的數組大小應該大於或等於第二個參數.
(1)先討論正確的傳參,如下代碼:
char a[] = "123";char b[] = "123456";// 也可以是char *a = "123";char *b = "123456";
char p1[4];char p2[9]; //[]中的數一定要大於等於第二個參數字符數組大小
char *p3;p3 = p1;
char *p4;p4 = p2;
strcpy(p1,a);strcpy(p2,b);
strcpy(p3,a);strcpy(p4,b);
以上代碼中實現復制是正確的.
(2)錯誤代碼一:
char a[] = "123"; char *p1;
char *p2 = "";
strcpy(p1,a); //--------1
strcpy(p2,b); //--------2
以上代碼編譯可以通過,但運行時1,2兩行都會出現錯誤並被退出.
原因是p1並沒有初始化,指向並不確定,將p1所指內容用"123"覆蓋會導致錯誤,
覆蓋p2也有可能修改原先指向的並不確定的值而導致錯誤
(3)錯誤代碼二:
char a[] = "123456";
char p[2];
strcpy(p,a);
printf("%s/n%s",p,a)
編譯不會出錯,運行結果為
123456
56
發現到,p的確得到了想要的值,但是a竟然被修改了
原因是,復制時具體的操作如下:
復制前的內存結構為p在前,a在後 :'/0' '/0' '/0' '/0' '1' '2' '3' '4' '5' '6' '/0'
p指向第一個'/0',a指向'1'.雖然聲明為p[2],但由於"內存對齊",編譯器自動補充兩字符並填'/0'
復制後的內存結構仍為p在前,a在後:'1' '2' '3' '4' '5' '6' '/0' '4' '5' '5' '/0'
p和a所指的內存地址並不會變,所以此時p指向的是'1',a指向的是'5'
因此就出現了上述的錯誤