C語言字符串中的指針與數組

先說一下字符串字面量(字符串常量):雙引號中的字符和編譯器自動加入末尾的\0字符,都作爲字符串儲存在內存中。字符串常量屬於靜態存儲類別,說明如果在函數中使用字符串常量,該字符串只會儲存一次,在整個程序的生命週期內存在,即使函數被調用多次。用雙引號扣起來的內容被視爲指向該字符串儲存位置的指針。

字符串的賦值可以用指針與數組,請看下面的例子

char str1[] = "I am a student"; 
const char *str2 = "I am a student too";

以上兩種表示方法還是有一些不同的

先說數組表示法,數組形式str1[]在計算機的內存中分配一個內含15個元素的數組(末尾還要加上空字符'\0'),當程序載入內存時,也載入了程序中的字符串,字符串存儲在靜態存儲區中,但是當程序在開始時纔會爲該數組分配內存,此時纔將字符串拷貝到數組中,注意此時字符串有兩個副本,一個是靜態存儲區中的常量,另一個是存儲在數組中的字符串。str1爲首元素的地址(&str1[0]),是常量地址,不能更改,可以進行str1+1(&str1[1]),但是不允許str++這樣的操作,因爲遞增運算符只能對變量名進行運算。

指針形式(*str2)也使得編譯器爲字符串在靜態存儲區預留19個元素空間,一旦開始執行程序,它會爲指針變量str2流出一個儲存位置,並把字符串的地址儲存在指針變量中,該變量最初指向該字符串的首地址,但它的值可以改變。因此可以使用自增運算符,如++str2將指向第二個字符。

總結一下,初始化數組把靜態存儲區的字符串拷貝到數組中,而初始化指針只把字符串的地址拷貝給指針。

看一下例子

#include <stdio.h>
#define MSG "I'm special"
int main(void) { 
	char str1[] = MSG; 
	const char * str2 = MSG;
	printf("address of \"I'm special\":%p\n","I'm special");
	printf("              address str1:%p\n",str1);
	printf("              address str2:%p\n",str2);
	printf("               address MSG:%p\n",MSG);
	printf("address of \"I'm special\":%p\n","I'm special");
	return 0;
}

運行結果爲:

address of "I'm special":0x4006e8
              address str1:0x7fff05a39f40
              address str2:0x4006e8
               address MSG:0x4006e8
address of "I'm special":0x4006e8

str2與MSG的地址相同,而與str1的地址不同。雖然字符串常量"I'm special"在兩個printf()函數中出現了兩次,但是編譯器只使用了一個存儲位置,而且與MSG的地址相同。

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