[英]Is a number between the 2 square brackets necessary regarding char variables
我剛開始在 C 編程,我在 inte.net 上看到人們聲明char
s,例如char name[]
,沒有在 2 個方括號之間放置任何數字。 我曾經在高中時用 C++ 編碼,我們總是在聲明 char 時放一個數字。 有人可以解釋我們什么時候放一個數字,或者在聲明char
變量時是否有必要使用一個數字?
我曾經這樣做:
char name[20] = "John";
但我在 inte.net 上看到有人這樣做:
char name[] = "John";
char curse[] = "fie! cometh h're and englut mine own coxcomb thee distemperate fooleth!";
在這種情況下,編譯器會自動計算字節數,包括空終止符。 數組的大小等於字符串的長度加上空字節。
char curse[100] = "fie! cometh h're and englut mine own coxcomb thee distemperate fooleth!";
然而,這定義了一個包含100
char
的數組,並用一個大約70
個字節的字符串對其進行了初始化。 字節的 rest 被初始化為0
¹。 數組的大小為100
個字節,而字符串的長度可以用strlen
確定。 注意數組的大小和它包含的字符串的長度是不一樣的。
旁白:最好將數組大小定義為宏,而不是在代碼中到處使用幻數。 這樣更容易維護。
[1] 來自 C11:
如果大括號括起來的列表中的初始值設定項少於聚合的元素或成員,或者用於初始化已知大小數組的字符串文字中的字符少於數組中的元素,則聚合的其余部分應與具有 static 存儲持續時間的對象一樣被隱式初始化。
即0
。
char name[] = "John";
將定義一個長度足以容納"John"
(5 個字符)的字符數組。
char name1[20] = "John";
定義了一個 20 個char
的數組,初始化字符串只需要 5 個字節(從 rest 字節中抽象出來)所以你可以使用剩下的 15 個字節,例如通過向它附加另一個字符串。
strcat(name1, " Travolta");
`
來自C標准(6.7.9初始化)
22如果初始化一個未知大小的數組,其大小由具有顯式初始化器的最大索引元素確定。 數組類型在其初始化列表的末尾完成。
和
14 字符類型的數組可以由字符串文字或 UTF-8 字符串文字初始化,可選地用大括號括起來。 字符串文字的連續字節(如果有空間或數組大小未知,則包括終止字符 null)初始化數組的元素。
所以在這個字符數組的聲明中
char name[] = "John";
這是根據 C 標准的第二個引述相當於
char name[] = { "John" );
數組name
由字符串文字"John"
初始化。
根據 C 標准的第一條引述,數組的大小由字符串文字中的字符數(包括終止零字符'\0'
)決定。 實際上上面的聲明和下面的聲明有同樣的效果
char name[] = { 'J', 'o', 'h', 'n', '\0' };
因此,由於字符串文字中的字符數等於5
,因此數組恰好有5
元素,並且其大小也等於5
,因為sizeof( char )
始終等於1
。
在這份聲明中
char name[20] = "John";
又可以寫成
char name[20] = { "John" };
該數組聲明為明確指定20
元素。 數組的前5
元素具有相應的顯式初始值設定項(字符串文字的字符)。 數組的所有其他元素均由0
隱式初始化。
注意C里面可以寫
char name[4] = "John";
也就是說,您可以從數組的初始值設定項列表中排除字符串文字的終止零字符'\0'
。 在這種情況下,數組name
將不包含字符串。 在 C++ 這樣的初始化是不正確的,C++ 編譯器將針對這樣的聲明發出錯誤。
例如,到 output 一個包含字符串的字符數組
printf( "name = %s\n", name );
對於最后顯示的聲明,其中聲明的數組不包含您可以編寫的字符串
printf( "name = %.*s\n", ( int )sizeof( name ), name );
如果聲明的數組沒有大小但帶有初始化程序,則數組的大小取自初始化程序中元素的數量:
int foo[] = {0, 1, 2, 3};
在這種情況下, foo
將是 4 個元素寬。
char bar[] = "fred";
char bar[] = { 'f', 'r', 'e', 'd', 0 };
在這種情況下, bar
將有 5 個元素寬——初始值設定"fred"
和{ 'f', 'r', 'e', 'd', 0 }
彼此等價。
如果您聲明一個具有大小和初始值設定項的數組,則大小將從大小表達式中獲取。 如果初始化器中的元素少於大小,則剩余元素將被初始化為 0:
int foo[10] = {1, 2, 3}; // elements 3 through 9 will be initialized to 0
如果初始化器中的元素多於數組的大小,那么這就是約束違規,編譯器會沖你大喊大叫:
int foo[3] = {1, 2, 3, 4}; // constraint violation, too many elements
// in the initializer
如果您使用指定的初始化器,那么大小將從初始化器的數量或最大的指定初始化器中獲取:
int foo[] = {[0] = 1, [9] = 2};
foo
將有 10 個元素寬,元素 0 將被初始化為 1,元素 9 將被初始化為 2,其余元素將被初始化為 0。
如果聲明的數組沒有大小且沒有初始值設定項,則數組類型是不完整的,您無法創建不完整類型的實例。
請注意,數組大小在數組的生命周期內是固定的。 C 有一個叫做可變長度數組的東西,其中數組的大小由運行時變量決定:
size_t x = some_size();
int arr[x];
但是,在此上下文中的“可變”僅表示數組的大小在定義之間不是固定的,而不是數組在定義后可以調整大小。
在function 參數聲明的上下文中, T a[N]
和T a[]
被“調整”為T *a
- 您不能將 arrays 作為 function 參數傳遞,因為在大多數情況下數組表達式“衰減”為指針表達式以及什么function實際接收的是一個指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.