1. 程式人生 > 其它 >字串指標與字元陣列的區別--字串常量的值不能改

字串指標與字元陣列的區別--字串常量的值不能改

技術標籤:C/C++

注:這裡對概念不是很清楚,應該不叫字串指標,C語言中不存在字串指標這個資料型別。

經常犯錯的知識點,以前也沒有理解,這裡再好好的記錄下。要經常溫固而知新。

用字元陣列和字元指標變數都可實現字串的儲存和運算。但是兩者是有區別的。在使用時應注意以下幾個問題:

1. 字串指標變數本身是一個變數,用於存放字串的首地址。而字串本身是存放在以該首地址為首的一塊連續的記憶體空間中並以‘\0’作為串的結束。字元陣列是由於若干個陣列元素組成的,它可用來存放整個字串。

2. 對字串指標方式

char *ps="C Language";

可以寫為:

char *ps;

ps="C Language";

而對陣列方式:

static char st[]={"C Language"};

不能寫為:

char st[20];

st={"C Language"};

而只能對字元陣列的各元素逐個賦值。

從以上幾點可以看出字串指標變數與字元陣列在使用時的區別,同時也可看出使用指標變數更加方便。

當一個指標變數在未取得確定地址前使用是危險的,容易引起錯誤。
一個錯誤的例子,如下:
char *name;
scanf("%s",name);
printf("%s",name);

有的編譯器雖然也能通過,但這是錯誤的,因為是個指標,定義時指向不可用的地址。解決這個問題有兩種方法:用陣列的方法或給字元針針分配記憶體空間的方法。
陣列的方法:
char name[20];
scanf("%s",name);
printf("%s",name);

給字元針針分配記憶體空間的辦法:
char *name;
name=(char*)malloc(50); //此時name已經指向一個剛剛分配的地址空間。
scanf("%s",name);
printf("%s",name);

但是對指標變數直接賦值是可以的。因為C系統對指標變數賦值時要給以確定的地址。

3.int main()
{
char str1[40]="hello world!"; //char *str1="hello world!";
str1[4]='A'; //若str1是指標型的,編譯通過,但執行是此處會段錯誤
printf("%s\n",str1);
return 0;
}


陣列和指標都可以在它們的定義中用字串常量進行初始化,儘管看上去一樣,底層的實現機制卻不相同。

定義指標時,編譯器並不為指標所指向的物件分配空間,它只是分配指標本身的空間,除非在定義的同時賦值給指標一個字串常量進行初始化。例如:下面的定義建立了一個字串常量(為其分配了記憶體):

char *p=”abcdefg”;

注意只有對字串常量才是如此,不能指望為浮點數之類的常量分配空間,如:

float *p=3.14; /*錯誤,無法通過編譯*/

下面結合一個例項談談初始化指標時建立的字串常量與陣列中的字串的區別:

  1. 在ANSI C中,初始化指標時所建立的字串常量被定義為只讀。如果試圖通過指標修改這個字串的值,程式就會出現未定義的行為。在有些編譯器中,字串常量被存放在只允許讀取的文字段中,以防止它被修改。
  2. 陣列也可以用字串常量進行初始化:

Char a[]=”abcdefg”;

與指標相反,由字串常量初始化的陣列是可以修改的。其中的單個字元在以後可以改變。

下面是一個在vc6中的一個例子,完成將一個字串中的所有大寫字母全部轉換為小寫字母的功能:

 #include<iostream.h>
 #include<ctype.h>
  
   /******************************************************************************/
  /*
   *    Convert a string to lower case
   */
  
  int strlower(char *string)
 {
     if(string==NULL)
     {
         return -1;
   }
 
     while(*string)
     {
         if(isupper(*string))
             *string=tolower(*string);
         string++;
     }
     *string='\0';
     return 0;
 }
 /*char *strlower(char *string)
 {
    char    *s;
 
     if (string == NULL) {
         return NULL;
     }
     s = string;
     while (*s) {
         if (isupper(*s)) {
             *s = (char) tolower(*s);
         }
         s++;
     }
     *s = '\0';
     return string;
 }
 */
 
 void main()
 {
     char *test="ABCDEFGhijklmN";
     strlower(test);
     cout<<test<<endl;
 }

其中,如果採用char *test=”ABCDEFGhijklmN”;會產生執行時錯誤。Char test[]=”ABCDEFGhijklmN”則程式正常執行,原因如前所述。