C/C++--char *s 和 char s[] 的區別

原文地址:http://duanhengbin.iteye.com/blog/1706635


  1. 最近的項目中有不少c的程序,在與項目新成員的交流中發現,普遍對於char *s1 和 char s2[] 認識有誤區(認爲無區別),導致有時出現“難以理解”的錯誤。一時也不能說得很明白,網上也搜了一下相關文章發現一些寫的比較好的,綜合了一下當教育資料備用。  
  2.    
  3. char *s1 = "hello";  
  4. char s2[] = "hello";  
  5.    
  6. 【區別所在】  
  7. char *s1 的s1,而指針是指向一塊內存區域,它指向的內存區域的大小可以隨時改變,而且當指針指向常量字符串時,它的內容是不可以被修改的,否則在運行時會報錯。  
  8. char s2[]的s2 是數組對應着一塊內存區域,其地址和容量在生命期裏不會改變,只有數組的內容可以改變  
  9.    
  10. 【內存模型】  
  11.        +-----+     +---+---+---+---+---+---+  
  12.    s1: |  *======> | h | e | l | l | o |\0 |  
  13.        +-----+     +---+---+---+---+---+---+  
  14.        +---+---+---+---+---+---+  
  15.    s2: | h | e | l | l | o |\0 |  
  16.        +---+---+---+---+---+---+  
  17.    
  18. 場景一)  
  19. char *s1 = "hello";  
  20. char s2[] = "hello";  
  21. s2=s1;  //編譯ERROR  
  22. s1=s2;  //OK  
  23.    
  24. 分析:s2其地址和容量在生命期裏不能改變  
  25.    
  26. 場景二)  
  27. char s2[] = "hello";  
  28. char *s1 = s2;  //編譯器做了隱式的轉換 實際爲&s2  
  29. 或  
  30. char *s1 = &s2;  
  31.    
  32. 分析:以上兩個指針復值完全等價,由於編譯器會做這個隱式轉換也容易導致初學者誤認爲 char *s 與char s[]是一回事。  
  33.       另用第二種在一些編譯器甚至會報警告信息。  
  34.    
  35. 場景三)  
  36. char *s1 = "hello";  
  37. char s2[] = "hello";  
  38. s1[0]='a';  //×運行ERROR( 這一句好像在一些的編譯器不會出錯,原因待查)  
  39. s2[0]='a';  //OK  
  40.    
  41. 分析:運行時會報錯,原因在於企圖改變s1的內容,由於s1指向的是常量字符串,其內容是不可修改的,因此在運行時不會通過。而s2指向的是變量區字符串,可以修改。  
  42.    
  43. 場景四)  
  44. 讓我們來給一個指針的指針賦值,在使用某些含char**參數的函數時會用到,場景二的增強版。  
  45.     char *s1="hello";  
  46.     char s2[]="hello";  
  47.     char *s3=s2;       //★注意這句必須要★  
  48.     char **s4=&s3;   //s2(char[])要用兩步才能完成賦值  
  49.     char **s5=&s1;   //s1(char*) 只需一步  
  50.     printf("s4=[%s]\n",*s4);//打印結果:s4=[hello]  
  51.     printf("s5=[%s]\n",*s5);//打印結果:s5=[hello]  
  52.    
  53. 分析:這個例子應當說最能反映出char *與char []的差異,但是由於使用場合不多,新人尤其需要注意。  
  54.    
  55. 下面是一些char *s1 和 char s2[]相同的地方(同樣編譯器對char[]做了隱式變化):  
  56. 1)作爲形參完全相同  
  57. 如:  
  58.    void function(char *s1);  
  59.    void function(char s1[]);  
  60.    
  61. 2)只讀取不修改的時候  
  62. 如:  
  63.     char *s1="hello";  
  64.     char s2[]="hello";  
  65.     printf("s1[1]=[%c]\n",s1[1]);   //s1[1]=[e]   
  66.     printf("s2[1]=[%c]\n",s2[1]);   //s2[1]=[e]   
  67.     printf("s1=[%s]\n",s1);         //s1=[hello]  
  68.     printf("s2=[%s]\n",s2);         //s2=[hello]  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章