c/c++ char*、char[]

一、本質區別

       一句話,char* s是一個保存字符串首地址的指針變量,char a[]是許多連續的內存單元,單元中的元素爲char類型。之所以用char *能達到char []的效果,還是字符串的本質,即給你一個字符串地址,便可以隨心所欲的操作它。但是,char*和char a[]的本質屬性是不一樣的。

      當定義 char a[10] 時,編譯器會給數組分配十個單元,每個單元的數據類型爲字符。而定義 char* s 時,這是個指針變量,只佔四個字節,32位,用來保存一個地址,如:

      printf("%p",s);//這個表示 s 的單元中所保存的地址。

      printf("%p",&s);//這個表示變量本身所在內存單元地址。

二、具體分析

例1:

char *s1 = "hello";

char s2[100] = "hello";

s1指向的內存區域的大小可以改變,而且指向常量字符串時,它的內容是不可以被部分修改的(不能以s1[x]='y'的形式修改,可以以s1[x]的形式來使用,跟數組一樣;但整體可以修改,如s1=“dasdasd”就可以)。

s2指向的內存區域的地址和容量在生命期裏不會改變,但數組裏存的內容可以改變。

(兩者在內存裏都在末位存了‘\0’,但strlen()時不計‘\0’。上述s1,s2的strlen()都是5


s2=s1;//錯,s2的地址不能變,即數組不能用等號賦值(除了初始化)

s1=s2;//對,相當於普通的非數組變量賦值

例2:

char *s1 和 char s2[]相同的地方(編譯器對char[]做了隱式變化):

1)作爲形參完全相同,如:

   void function(char *s1);

   void function(char s1[]);

2)只使用不修改,如:

    char *s1="hello";

    char s2[]="hello";

    printf("s1[1]=[%c]\n",s1[1]);   //s1[1]=[e] 

    printf("s2[1]=[%c]\n",s2[1]);   //s2[1]=[e] 

    printf("s1=[%s]\n",s1);         //s1=[hello]

    printf("s2=[%s]\n",s2);         //s2=[hello]

例3:

char  str[10] = {"hello world"};

printf("%s",str); 

//用首地址就可以輸出字符串,因爲在C語言中字符串常量的本質表示其實是一個地址

      char  *s ;

      s = "hello";

     把一個字符串賦給一個指針變量居然沒出錯,這是因爲C語言中編譯器會給字符串常量分配地址,字符串常量的本質表示其實是一個地址。如果"hello"存儲在內存中的 0x2000 0x2001 0x2002 0x2003 0x2004 0x2005 。

      s = "hello" ,就是把“hello”的首地址給了s,其實真正的意義是 s ="hello" = 0x2000;

      我們將“hello”看作是字符串,但是編譯器把它看作是地址 0x2000,即字符串常量的本質表現是代表它的第一個字符的地址。

      那麼 %s ,它的原理其實也是通過字符串首地址輸出字符串,printf("%s ", s);   所以,printf("%s",地址);也是等效的。

發佈了31 篇原創文章 · 獲贊 31 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章