簡體   English   中英

使用指針初始化const數組

[英]Initialize a const array with a pointer

為什么第一行有效但其余行無效。 我雖然第一個是第二個的速記。

const char *c = "abc"; // Why valid?

const char *b = { 'a' , 'b', 'c', '\0' }; // invalid

const int *a = { 1, 2, 3, 0 }; // invalid

這里真正的區別是"abc"char[]類型的字符串文字,而{'a', 'b', 'c', 0}則不是。 您可以輕松地使用它來初始化完全不同的類型,例如:

struct s{
  char c;
  int i, j;
  float f;
} x = {'a', 'b', 'c', 0};

所以當你寫const char *b = { 'a' , 'b', 'c', '\\0' }; ,編譯器選擇隱式轉換{'a'} -> 'a'並嘗試用它初始化你的指針。 根據編譯器和實際值,這可能會也可能不會失敗,例如,許多編譯器會解釋const char *b = { '\\0' }; b初始化為NULL指針而不是像預期的那樣將空字符串初始化。

如果要初始化指向使用列表初始化創建的數組(或任何其他類型)的地址的指針,則應顯式轉換:

const char *b = (const char[]){'a', 'b', 'c', 0};
const int *a = (const int[]){'a', 'b', 'c', 0};
struct s *x = &(struct s){'a', 'b', 'c', 0};

在第一種情況下,您有一個字符串文字,它是char數組,在此上下文中它將轉換為指向char的指針。

在接下來的兩種情況下,您嘗試使用列表初始化來初始化一個指針,該指針將嘗試將列表的第一個元素轉換為生成警告的指針,因為char或int都不是指針,這與以下方式相同:

const char *b = 'a' ;

如果列表中有有效的指針,它對第一個元素可以正常工作,但由於你有更多的初始值而不是變量,因此格式不正確。

數組和指針不是一回事。

const char *c = "abc";

初始化帶有字符串常量地址的指針。 Sting常量包含在其他地方(不在堆棧上,通常是特殊的全局常量區域)。

const char c[] = "abc";

初始化具有給定字符的chars數組(具有給定字符串的內容)。 這個將在堆棧上。

第一行是有效的,因為C標准允許創建常量字符串,因為它們的長度可以在編譯時確定。

這同樣不適用於指針:編譯器無法決定是否應該為堆中的數組(例如,正常的int [] )或常規內存中分配內存,如malloc()

如果將陣列初始化為:

   int a[] = { 1, 2, 3, 0 };

然后它變得有效,因為現在編譯器確定你想在堆(臨時)內存中有一個數組,並且在你離開聲明它的代碼部分后它將從內存中釋放出來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM