2014-02-23 151 views
0

請看下面的代碼片段字符數組初始化

char ch[10] = "hello"; // is ok 

char ch[10]; 
ch = "hello"; // showing lvalue error 

它應該有根據該數組衰變爲pointer.Why概念有可能在這裏通道不衰減到char *? 請描述兩者之間的區別。

+0

你知道什麼是「左值」嗎? –

+0

是的。這些是佔用內存空間並且可以指定或不可指定的值。 – YakRangi

+0

是,左值是可賦值的值。在你的情況下,ch指向它自己的第一個元素的地址,即它的基地址。所以你不能改變數組的基地址,而你可以改變數組的基地址的值。因此在這種情況下'ch'不是'lvalue'。請參閱我的答案以供參考 –

回答

1

殼體1: -

char ch[10] = "hello";

取的基地址爲1000

通過您的聲明

1000 - >ħ
1001 - >電子
1002 - > l
1003 - > l
1004 - >ö
1005 - > \ 0

和CH指向1000

殼體2: -

char ch[10];
ch="hello";

1000 - >垃圾
1001 - >垃圾
1002 - >垃圾
1003 - >垃圾
1004 - >垃圾
1005 - >垃圾

注意hello是具有它自己的地址的獨立字符串,因此通過ch="hello"

您試圖ch"hello"指向的h新地址。

這是不可能的,因爲ch的類型是char *const

我的意思是說ch將始終指向它的基地址,並且不能更改數組的基地址。

您可以更改數組的值,但不能更改數組元素的地址。

0

無法使用賦值運算符(如第二個示例)在C中定義整個數組的內容。第一個例子是該規則的一個例外:在定義點初始化文件是合法的。

「數組衰減爲指針」不是描述指針/數組對偶性的正確方法:數組僅在作爲參數傳遞給函數時才轉換爲指向其第一個元素的指針。只有當元素是數組的第一個元素時,才能使用[]對指向元素的指針進行索引。如果沒有,編譯器不會抱怨,但結果是未定義的。

與應用於指針不同的是,大多數其他操作符在應用於數組時是非法的。

+2

「無法使用C初始化整個數組,例如您的第二個示例。」 - 您將初始化與賦值混淆。你當然可以*初始化一個數組。 –

+1

*「只有當數組作爲參數傳遞給函數時,數組才被轉換爲指向其第一個元素的指針」* - 不正確。例如; 'char c [size]; char * p = c;'或'char a [10]; char c = *(size + 5);'。 *「只有元素是數組的第一個元素時,纔可以使用[]指向元素的索引,否則編譯器不會抱怨,但結果是未定義的。 char a [10]; char * p = &a[5]; char c = p [2]'是完全有效的。對不起,這是一個很文雅的人,但是,你知道......這就是我們所做的。 –

+0

:D你是絕對正確的!這對我來說太早了,我沒有清楚地想... –

0

ch =「hello」不是初始化,它是分配。還有"hello"類型和ch類型是不同的。

將其更改爲char ch[10] ="hello"

2

數組不可分配。如果你需要動態地分配一個字符串,那麼你要麼A)事先創建一個固定長度的緩衝區並填充它,要麼B)動態地分配內存,並且再次填充它。

這一切都取決於你是否事先知道大小(雖然C支持可變長度數組,但要小心),或者如果你需要容納任意長度的字符串。

爲字符串複製到現有的緩衝液(用自動存儲持續時間或以其他方式分配),可以使用strcpystrncpy(用於插入到現有的字符串),strdup(POSIX),與fgets,或任何其他方法來讀取它在是適當的。請注意緩衝區大小和字符串長度。

1

char ch[10]; 
ch = "hello"; 

不是C.無效宣告你的陣列後,你不能將其重新分配。數組的名稱實際上是該數組的第一個元素的地址。 ch是一個數組,hello也是數組,它沒有名稱但具有它自己的地址,所以此ch = "hello";行是嘗試使用另一個地址重新分配ch,這是無效的。 你只

strcpy(ch,"hello"); 

爲了能夠把hello進去

2
char ch[10] = "hello"; 

是初始化,並通過標準允許的。它實際上「給我一個十個字符的數組,並用C字符串"hello"填充它。

char ch[10]; 
ch = "hello"; 

是(企圖)分配,並且是不允許的。你可以這樣做:

char *ch; 
ch = "hello"; 

但你結束了,你不允許修改ch(這是不確定的行爲是否或不是你不允許修改字符串常量)。

一種方式來獲得「轉讓」初始化時間後與陣列發生的事情是:

char ch[10]; 
strcpy (ch, "hello"); 
2

你應該明白初始化和賦值的區別。初始化定義了一個變量,並在同一個語句中給它賦值。以下語句定義類型爲char[10]的變量ch - 10個字符的數組,然後爲其指定字符串文字。

char ch[10] = "hello"; 

這相當於

char ch[10] = {'h', 'e', 'l', 'l', 'o', '\0'}; 

請注意,您只分配陣列ch的第一6元素,其餘4被隱式初始化爲空字符 - '\0'。因此,上述兩種說法有一樣的:

char ch[10] = {'h', 'e', 'l', 'l', 'o', '\0', '\0', '\0', '\0', '\0'};  

的任務是當你第一次定義一個變量,然後在另一份聲明中爲它分配一個值。

char ch[10]; // define ch of type char[10]. contains garbage right now. 

只是因爲它包含垃圾值定義後,則不應使用ch。接下來,你應該爲它賦值,但是不能像初始化時那樣賦值。這是C的規則所不允許的。您不能一次性分配數組的所有元素,但必須分別分配數組中的每個元素。

char ch[10]; 
const char *s = "hello"; 
int len = strlen(s); 
for(int i = 0; i <= len; i++) // copy the null byte as well 
    ch[i] = s[i]; 

在這裏,你只分配數組ch的第一6元素,其餘4仍然含有垃圾值,除非你將它們分配。這是數組初始化和賦值之間的區別。