關於C++中char型數組、指針及strcpy函數的細節觀察


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

   3456 

   發現到,p的確得到了想要的值,但是a竟然被修改了

   原因是,復制時具體的操作如下:

   復制前的內存結構為p在前,a在后  :'/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' '6' '/0'

   p和a所指的內存地址並不會變,所以此時p指向的是'1',a指向的是'3'

   因此就出現了上述的現象

 這個是在codeblocks里面測試的,如果定義p[3]的話,結果a會是456,也就是說,在這里p不存在一個內存對齊的概念

 而其他的編譯器可就不一定是這樣了,可能會在進去之前給p分配四個字節的空間,那樣的話,在輸出a的時候應該就是 56 了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM