1.char str[] = "hello"; //legal
2.char str1[];
str1 = "hello"; // illegal
我知道「hello」返回字符串文字池中不能直接賦值給數組變量的字符串的地址。在第一種情況下,來自「hello」文字的字符被逐個拷貝到數組中,並在末尾添加'\ 0'。與賦值不同的初始化?
這是因爲賦值運算符「=」在這裏被重載以支持這個嗎?
我也想知道其他有趣的情況,其中初始化與賦值不同。
1.char str[] = "hello"; //legal
2.char str1[];
str1 = "hello"; // illegal
我知道「hello」返回字符串文字池中不能直接賦值給數組變量的字符串的地址。在第一種情況下,來自「hello」文字的字符被逐個拷貝到數組中,並在末尾添加'\ 0'。與賦值不同的初始化?
這是因爲賦值運算符「=」在這裏被重載以支持這個嗎?
我也想知道其他有趣的情況,其中初始化與賦值不同。
您不能認爲它是重載(其中不存在C反正),因爲字符數組與字符串文字的初始化是一個特例。字符串文字的類型是const char[N]
,所以如果它類似於重載,則可以使用任何類型爲const char[N]
的表達式來初始化char數組。但你不能!
const char arr[3];
const char arr1[] = arr; //compiler error. Cannot initialize array with another array.
語言標準只是說字符數組可以用字符串文字初始化。由於他們對分配沒有提及,因此一般規則適用,特別是不能分配數組。
至於其他情況,當初始化與賦值不同時:在C++中,有引用和類的地方,會有無數個例子。在C語言中,沒有完全成熟的類或引用,我能想到的把我的頭頂部的唯一的另一件事是const的變量:
const int a = 4; //OK;
const int b; //Error;
b = 4; //Error;
又如:數組初始化用大括號
int a[3] = {1,2,3}; //OK
int b[3];
b = {1,2,3}; //error
同樣的,結構
數組具有不可修改的地址。你需要一個指針作爲可修改的左值。
通過分配(嘗試)到一個常量字符串文字,您正在獲取它的地址。不同的地址導致非法性。
「hello」在內存中分配一些空間並給出地址。然後你把它的地址初始化數組。
如果你想把它看作是運算符被超載(即使C不使用這個術語),你當然可以這樣做。
你是否也認爲這是超載:
unsigned char x;
double y;
x = 2;
y = 1.243;
那些被分配完全不同類型的數據,畢竟,而是使用了「同一個運營商」,對不對?
這只是不同,要初始化或分配。
另一個很大的區別是您曾經能夠初始化結構,但是以後的賦值沒有相應的「結構字面量」語法。至於C99,我們現在有compound literals。
您可以給我其他初始化與基本數據類型的賦值不同的實例嗎? –
@NithishInpursuitOfhappiness'struct'就是這樣一個例子:'struct x {int a; char c; } a = {1,'1'};'是有效的,但後來你不能做'a = {2,'1'};' –
@GrijeshChauhan你讀過我的回答了嗎?在C99中(這不是真的新的),你一定可以做到:'a =((struct x){2,'a'});'。 – unwind
char str[] = "hello";
是數組初始化,通過在C定義的,因爲字符串初始化是如此普遍語法糖。編譯器在你的程序中分配一些固定的內存並初始化它。數組(str)的名稱評估爲該存儲器的地址,並且不能更改,因爲沒有包含該地址的變量。
Grijesh Chauhan解釋了更多細節。
其他情況取決於你的意思。擴展目前的情況,可以很容易地看到其他初始化陣列具有相同的屬性,例如
int a[] = { 1, 2, 3, 4 };
謝謝感謝,但知道我刪除了我的答案,因爲我認爲數組查找其他例子初始化,那些在賦值無效,回答基於標題 –
實際上'char str1 [];'也是非法的。 – banarun
@banarun是的,你是對的。我們需要聲明數組的大小。 – 0decimal0