[英]ANSI C - initializing an array
我一直在做的是:
int arr[] = {2, 3, 4};
並且一直有效。
我聽說過使用指針初始化新數組的更好方法:
int *arr = {2, 3, 4};
但是,它在任何IDE中均不起作用,它會引發一些錯誤,例如int differs in levels of indirection from int
,或者too many initializers
。 我應該怎么做?
int arr[] = {2, 3, 4};
很好,而且完全正確。 無需更改。
在gcc上,該初始化似乎對我有用,但不正確。
int *arr = {2, 3, 4}; //weird behaviour, stores first value `2` as read-only
int arr[] = {2, 3, 4}; //array decl
前者不是初始化數組的正確方法。
對於char * ,這更有意義
char* arr = "abcde"; //Pointer to a read-only char array in memory
char[] arr = "abcde"; //Normal char array
區別:
前者被寫入到程序集的Rodata (常量,只讀數據)部分,而后者則位於讀/寫Data-Segment中 。 嘗試更改前者可能會導致segmentation-fault 。
值的存儲位置不同。
char* arr = "abcde";
arr[1] = 'f'; //(undefined behavior)
char[] arr2 = "abcde";
arr2[1] = 'f'; //no issue
如果要“初始化數組”,則必須初始化一個數組 ,而不是一個指針。
無論如何,在C99中可以使用復合文字,並且可以將指針初始化為
int *arr = (int []) {2, 3, 4};
這與您嘗試執行的操作很接近。 盡管術語“ ANSI C”通常用於指代C89 / 90,但該功能不可用。
這種方法沒有“更好”的選擇。 它只是給您一個指針而不是一個數組,因此這實際上是您需要什么的問題。
為什么第二個版本會比第一個版本好?
至少第一個版本是顯式的:您使用給定的元素定義一個int數組。 讓編譯器確定如何最佳地執行此操作。
從您的評論轉到Evan Li(“字符串也是一種數組,並且使用指針對其進行了初始化。因此,數組也應以這種方式進行初始化。”)。 如果講師確實告訴過您,我會認真考慮尋找新的講師,因為他對事情感到困惑。
字符串文字是數組表達式。 文字“ Hello”是char
的6個元素的數組(在C ++中為const char
)。 字符串文字的存儲方式是在程序的生命周期內分配它們的內存。 該內存可能是只讀的,也可能不是只讀的,具體取決於平台。 嘗試修改字符串文字內容的行為是未定義的 ,這意味着您可能會遇到段錯誤,或者可能會修改字符串,或者發生其他情況。
當數組表達式出現在上下文中而不是作為sizeof
或一元&
運算符的操作數時,或者在聲明中使用字符串常量來初始化另一個數組時,表達式的類型將被轉換(“ decays”) “ T
N個元素數組”到“指向T
指針”,表達式的值是數組的第一個元素的地址。
這就是為什么你可以寫像
char *foo = "This is a test";
字符串文字"This is a test"
是類型為“ 15個元素的char
數組"This is a test"
的數組表達式; 因為它不是sizeof
或&
運算符的操作數,並且不用於初始化另一個char
數組,所以表達式的類型變為“ char
指針”,並且第一個字符的地址分配給foo
。 通過對比,
char foo[] = "This is a test";
將foo
聲明為char
數組 ; 從初始化程序字符串的大小(15個字符)計算出大小,並將字符串文字的內容復制到foo
。
字符串是數組表達式; 大括號括起來的值列表不是 。
int *foo = {1, 2, 3};
不會創建一個3元素的int
數組,並將第一個元素的地址分配給foo
; 相反,如果我正在閱讀此權限,則應該違反約束:
6.7.9初始化
約束條件
2初始化程序不得嘗試為未包含在正在初始化的實體內的對象提供值。
從C99開始,您可以使用所謂的復合文字 ,如下所示:
int *foo = (int []) {1, 2, 3};
強制轉換表達式(int [])
是必需的。 這確實創建了一個新的3元素int
數組,並將第一個元素的地址分配給foo
。 與字符串文字不同,此類復合文字僅在封閉塊1的持續時間內存在; IOW,如果您做了類似的事情
int *foo = NULL;
if (condition())
{
foo = (int []){1, 2, 3};
// do stuff
}
// do more stuff
foo
指向的匿名數組對象僅存在於if
塊中; 一旦if
塊退出,該數組將不再存在,並且foo
的值不再有效。
static
持續時間,並且在程序的生存期內存在。
int arr [] = {2,3,4}; 還可以
如果要使用指針,則必須使用例如malloc分配內存。 像這樣:
int *arr = malloc(sizeof(int)*4);
arr[0]=1;
arr[1]=2;
arr[2]=3;
arr[3]=4;
//display
printf("%d %d %d %d\n",arr[0],arr[1],arr[2],arr[3]);
free(arr);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.