const
char
* p =
"hello world!"
;const
char array=
"hello world!"
;
以上兩種宣告,p和array都使用了字串「hello world!」的位址。在這種情況下,帶雙引號的字串本身決定了預留給字串的儲存空間,但這兩種形式並不是完全相同的。
陣列形式和指標形式有何不同呢?
**陣列形式(array)**在計算機的記憶體中分配乙個內含13個位元組的陣列,該陣列中每個元素被初始化為字串字面量對應的值。通常,字串「hello world!」都作為可執行檔案的的一部分儲存在資料段中(靜態儲存區)。當程式執行時,才會為陣列array分配記憶體,此時才會把字串從資料段拷貝到陣列,即array中的值為原始字串的乙個副本,而原始字串依舊原封不動地儲存在資料段。並且array被編譯器識別為備份字串的首位址別名,為位址常量不可更改,即++array之類的操作都是錯誤的。
**指標形式(p)**與陣列形式不一樣,從定義開始,指標p就儲存著原始字串「hello world!」的首位址,並且指標p的值是可以改變的,即++p操作是合法的,表示指向下乙個字元『e』。
總之,初始化陣列是把靜態儲存區的字串拷貝到陣列中,而初始化指標只是把字串的位址拷貝給指標。
——————————————————————————————
#include
#define msg "i love china."
intmain
(int argc,
char
const
*ar**)
輸出結果:
adddress of "i love china."
: 0x7f22cc200826
address of array: 0x7fffcac294ca
address of p: 0x7f22cc200818
address of msg: 0x7f22cc200818
adddress of "i love china."
: 0x7f22cc200826
從程式輸出的資料可以看出:
p與msg的位址是相同的,而array的位址是不同的,所以是符合上面的結論的;
兩次printf函式列印的「i love china.」的位址是一樣的,說明兩次在字串都儲存在同乙個位置,但是卻與msg的位置不同,說明編譯器編譯的時候可以把多次使用的相同的字面量的字串儲存在一處或多處。
對於沒有使用const限定符的指標初始化,能否使用該指標來修改這個字串呢?
char
* word =
"big"
;word[0]
='p'
;// 是否允許呢?
編譯器可能是允許這樣做,但是對於標準c此行為是未定義的。因為word指標的初始化是將字串「big」的首位址賦值給word,而字串「big」還是儲存在資料段中,並沒有備份到其他位置(與上述array陣列初始化方式區別),而根據上述歷程,編譯器有可能使用記憶體中的乙個副本來表示完全相同的字串字面量,所以直接使用指標修改了字串有可能會直接影響到所有使用到該字串的**。因此,建議把指標初始化為字串字面變數時使用const限定符。如下:
const
char
* word =
"big"
;
C語言指標陣列和陣列指標
初學者總是分不出指標陣列與陣列指標的區別。其實很好理解 指標陣列 首先它是乙個陣列,陣列的元素都是指標,陣列佔多少個位元組由陣列本身決定。它是 儲存指標的陣列 的簡稱。陣列指標 首先它是乙個指標,它指向乙個陣列。在32 位系統下永遠是佔4 個位元組,至於它指向的陣列佔多少位元組,不知道。它是 指向陣...
C語言指標陣列和陣列指標
初學者總是分不出指標陣列與陣列指標的區別。其實很好理解 指標陣列 首先它是乙個陣列,陣列的元素都是指標,陣列佔多少個位元組由陣列本身決定。它是 儲存指標的陣列 的簡稱。陣列指標 首先它是乙個指標,它指向乙個陣列。在32 位系統下永遠是佔4 個位元組,至於它指向的陣列佔多少位元組,不知道。它是 指向陣...
C語言指標陣列和陣列指標
初學者總是分不出指標陣列與陣列指標的區別。其實很好理解 指標陣列 首先它是乙個陣列,陣列的元素都是指標,陣列佔多少個位元組由陣列本身決定。它是 儲存指標的陣列 的簡稱。陣列指標 首先它是乙個指標,它指向乙個陣列。在32 位系統下永遠是佔4 個位元組,至於它指向的陣列佔多少位元組,不知道。它是 指向陣...