字符數組、字符指針和字符串

   一、字符數組、字符串和‘\0’的關係

                        許多人理不清字符數組和字符指針及字符串之間的關係,其實編譯器把它們分得很清楚。
                    字符數組就是元素爲字符的數組,而字符串則是以‘\0'(ASCII碼值爲0x00)爲結束字符的字符數組。可見,字符數組並不一定就是字符串。
而對於字符串來說,它是可變長的,因此它無法記錄自己的長度。但是,如何來表示字符串的結束呢?它本身沒有長度信息,因此必須用一個字符來標記字符串的結束,這就是'\0'的來歷。由於字符串的連續性,編譯器沒有必要通過它的長度信息來提取整個字符串,僅通過一個指向其開頭字符的字符指針就能實現對整個字符串的引用。
                  
                   也就是說,如果用一個字符串字面常量來初始化一個字符數組,數組的長度至少要比字符串字面長度大1,因爲還要保持結束符'\0'.例如:
                   char array[] = "Hello"
                    數組array的元素爲{’H‘,'e','l','l','o','\0'}.

                

    二、字符數組、字符串和字符指針使用誤區。

              對於字符數組來說,它並不在乎中間或末尾有沒有'\0'結束字符,因爲數組知道它自己有多少個元素,況且'\0'字符對它來說,也是合法的元素。問題就在於:你可能會把字符數組當做字符串來使用,可能使用字符指針(例如 char* p)來引用一個字符數組。在這種情況下,用來操作字符串的庫函數(例如 strlen, strcpy)等並不知道這個字符串是來自於一個字符數組,因爲你傳遞進入的僅僅是一個字符指針,而字符指針除了它的類型和值外並不包括其他任何信息。這些庫函數總是假定你提供的字符指針指向的內存空間中的某個字符存放着那麼一個'\0',他們會很傻的直到找到第一個'\0'字符時纔會罷休。於是危險出現了:如果此時你的字符數組中沒有'\0'結束標誌,那麼把它當做字符串來使用的時候就會導致“內存訪問衝突”或者篡改了其他內存空間。

           如果你能保證總是使用數組下標來訪問字符數組中的每個元素,那麼就沒有必要在字符數組的結尾放一個'\0'。但是我們都無法做出這樣的保證,因爲在大多數情況下總是把字符數組用做字符串的緩衝區,所以應當在字符數組的結尾處放入這個麻煩的'\0'.

 

三、字符指針的誤區

         當你使用字符指針來引用一個字符變量的時候,千萬要小心,因爲C++/C 默認 char* 表示字符串。
         例如:
                 char ch = 'a'                   //用字符’a'來初始化字符變量ch
                 char *pChar = &ch         //字符指針指向字符變量
                 cout << pChar <<endl;   //錯把字符指針當做字符串


         正確的做法是:
                cout << *pChar << endl;  //取一個字符


  

四、字符串拷貝和比較

       字符串的拷貝請使用庫函數strcpy 和 strncpy,不要企圖用“ = ” 對字符串進行拷貝,因爲那是字符指針的複製。
       同理不要用“ == ” “ >= ” " != " 符號直接比較兩個字符串,字符串的比較應該是使用strcmp,strncmp等庫函數

       對字符串進行拷貝時,要保證函數結束後目標字符串的結尾有'\0'的結束標誌。某些字符串函數並不會自動在字符串結尾追加'\0',
       例如strncpy 和strncat,c除非你指定的n值比源串的長度大1,strcpy 和 strcat 會把源串的結束字符一併拷貝到目標中。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章