[英]What really happen when I defined array
我編寫程序來了解數組和指針之間的區別:
#include <stdio.h>
void main()
{
char arr [] ="hodaya",*ptr=arr;
printf("arr=%p\n",arr);
printf("&arr=%p\n",&arr);
printf("ptr=%p\n",ptr);
printf("&ptr=%p\n",&ptr);
}
結果:
arr=0xbfd26265
&arr=0xbfd26265
ptr=0xbfd26265
&ptr=0xbfd26260
所以我讀了下面的答案:
它回答了我的大多數問題,我只剩下一個問題!
我了解,當我定義指針時,我定義了(在特定地址中)用於保持地址的空間,因此我可以采用這樣的指針地址: &ptr
。
但是,當我定義數組時會發生什么?
首先,除非您的編譯器文檔明確列出void main()
作為main
函數的有效簽名,否則請使用int main(void)
。 在大多數情況下, 應該將main
返回一個值到運行時環境(即使只是EXIT_SUCCESS)。
所以我們來談談宣言
char arr [] ="hodaya";
"hodaya"
是字符串文字 ; 它存儲為7個元素的char
數組(6個字符加0的終止符),以便在程序啟動時進行分配並保持到程序退出。 字符串文字不是可修改的,嘗試更新一個字符串會導致未定義的行為(這可能意味着您的代碼因訪問沖突而崩潰,無法按預期工作)。 您應該始終將字符串文字視為只讀,並且永遠不要將其傳遞給嘗試對其進行修改的函數(例如strcpy
, strtok
等)。
arr
被聲明為char
數組,它將使用字符串常量"hodaya"
的內容進行初始化 。 數組的大小取自初始化器(7)的大小。 該聲明大致等於:
char arr[7];
strcpy( arr, "hodaya" );
也可以寫成
char arr[] = {'h', 'o', 'd', 'a', 'y', 'a', 0 };
結果相同( arr
初始化為字符串"hodaya"
),語法略有不同。 在這種情況下,不會創建字符串文字。
由於您聲明了arr
在main
本地(據說具有自動存儲持續時間 ,這意味着函數退出時將釋放內存),因此您可以通過arr[6]
修改arr[0]
的內容。
現在讓我們談談ptr
的聲明。
除非它是sizeof
或一元&
運算符的操作數,或者是用於在聲明中初始化另一個數組的字符串文字,否則類型為“ T
N元素數組”的表達式將被轉換(“ decay”)為類型為“指向T
指針”的表達式,該表達式的值將為數組中第一個元素的地址。 結果不是左值 ; 也就是說,它不能成為任務的目標。
這很重要,並且引起很多混亂。 arr
不是指針 ; 它不包含地址。 當編譯器在大多數情況下看到arr
時,它將用其第一個元素的地址替換它,並且所得表達式的類型將為char *
。 但是,如果arr
是一元&
運算符的操作數,則不會發生替換。 表達式的值相同(數組的地址與數組的第一個元素的地址相同),但是表達式的類型不同。 代替char *
, &arr
的類型是char (*)[7]
(指向char
7元素數組的指針)。
因此,在聲明中
char *ptr = arr;
arr
不是一元&
運算符(或任何其他運算符)的操作數,因此適用轉換規則,並且arr
第一個元素的地址寫入ptr
。
到您完成時,您的內存看起來類似於以下內容(地址並不旨在反映任何現實世界的體系結構):
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
"hodaya" 0x40040 'h' 'o' 'd' 'a'
0x40044 'y' 'a' 0 ??
...
arr 0x7fffb220 'h' 'o' 'd' 'a'
0x7fffb224 'y' 'a' 0 ??
ptr 0x7fffb228 0x7f 0xff 0xb2 0x28
同樣, arr
和ptr
僅在main
函數的生存ptr
存在。 字符串文字"hodaya"
在整個程序的生命周期中都存在。
注意:我使用gcc 4.1.2在一個SLES 10盒上編譯了上面的示例(在修復了一些問題之后),是的,即使僅用於初始化arr
,它也為.rodata
的字符串文字創建了一個條目。
arr
保存數組( &arr[0]
)中第一個元素的地址。
在這里,您始終在讀取元素的地址,而不是值。
arr[0] = 'a', arr[1] = 'b', arr[2] = 'c', arr[3] = 0;
char *ptr = arr;
*ptr++ = 'a', *ptr++ = 'b', *ptr++ = 'c', *ptr = 0;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.