2016-08-13 62 views
-2

我有一個問題,以更好地理解數組和空字節如何工作在C中。C數組和空字節

比方說,我有一個13個單元格的int數組。 比方說,我希望細胞數量:1,2,3和10有一個值。其他剩下的默認值會自動獲取nullchar \ 0作爲值?

我對\ 0的理解是,nullbyte總是在數組的末尾,它的功能是告訴程序數組在哪裏結束。但似乎是錯誤的

我寫了一個簡單的PROG鍵確認,似乎是這樣的:

int nums[13] = {1,2,3}; 
nums[10] = 69; 
int i; 
for(i=0;i<13;i++) { 
    if(nums[i]=='\0') { 
     printf("null char found! in position: %d\n",i); 
    } 
    else { 
     printf("element: %d found in position: %d of int array\n",nums[i],i); 
    } 
} 

return 0; 

這裏是輸出:

元素:1的位點發現:INT 0陣列

元件:2的位點發現:int數組的1

元件:3在位置上發現:int數組的2

發現空字符!在位置:3

找到空字符!在位置:4

找到空字符!在位置:5

找到空字符!在位置:6

找到空字符!在位置:7

找到空字符!在位置:8

找到空字符!在位置:9

元件:69在位置上發現:int數組的10

空焦炭找到!在位置:11

找到空字符!在位置:12

| 1 | | 2 | | 3 | | \ 0 | | \ 0 | | \ 0 | | \ 0 | | \ 0 | | \ 0 | | 69 | | \ 0 | | \ 0 | | \ 0 |

那麼爲什麼默認單元格設置爲\ 0值?而不是被留下空作爲例子?

空字符不應該只在整個數組的末尾一次? 謝謝

+0

對於標量,靜態分配的內存填充0或對指針填充NULL(\ 0)。如果你把\ 0作爲標量,它將被轉換爲0.沒有「空」之類的東西。您不應該將NULL(\ 0)與int進行比較,而是使用文字0. – Tibrogargan

+4

「我對\ 0的理解是,nullbyte總是在數組的末尾..」是完全錯誤的。您正在混淆常規數組和C字符串。 – usr2564301

+0

@Tibrogargan'\ 0'(NUL字符)與'NULL'指針不同。 '\ 0'是一個所有位都設置爲0的字節,它總是與「int」0相等。 – Kninnug

回答

3

在C中沒有要求陣列最後需要\0。 NUL-終止子僅僅用於字符串(其通常具有charwchar_t或其他字符類型)的C 字符串。在C字符串中,\0字節也不必位於包含它的數組的末尾,但它必須位於字符串部分的末尾。在陣列中的任何位置都有0是完全有效的。但是,如果該數組用作字符串,那麼標準C字符串函數將解釋具有最低索引的0來表示字符串的結尾。

當在

int nums[13] = {1,2,3}; 

聲明在C變量(nums)配有一個初始化({1,2,3})未在初始化(3至12)中提到的所有索引具有其值初始化爲0。數組中沒有「空」單元是不可能的。所有的單元格都會有一個值,這取決於程序(mer)什麼值可以被視爲空的。

1

C類型對應於內存,而內存沒有真正的「空」概念。有些語言可以通過放置一些「空」常量(例如Python有None)來使所有(或幾乎)都變爲「空」,但C不允許這樣做。不允許的原因之一是它迫使你對空的狀態有一個特殊的通用模式,並且這具有低層次的影響。例如,一個字符可以包含從0到255的任何值。這是因爲字符佔用8位。如果您還希望在不犧牲可能的字符值的情況下擁有一個空狀態,那麼您至少需要再多一位,因爲可以出於合法原因使用其他8位,並且由於很多原因,這是不受歡迎的。

對於您的數組,您正在使用的初始化語法將每個未指定的元素設置爲零。如果你寫:

char foo[4] = {1, 2, 3, 4}; 

然後每一個元素都有一個值(注意它到底沒有空字節,因爲數組並不需要必須在一個空字節結束,但是,如果你是使用它們作爲字符串,那麼他們非常應該)。如果你寫:

char foo[4] = {1, 2}; 

元素0和1有一個規定值,但2和3不這樣做,並與下面的語法C會認爲你想給他們爲零。在另一方面,如果你寫:

char foo[4]; 

你沒有給予任何價值的任何元素,在這種情況C不會在所有的數組初始化。從它讀取它將是未定義的行爲;在實踐中,通常情況下,元素將採用之前存儲在其存儲位置的任何值。

-1

首先,你正在將C字符串與常規數組混淆。對於字符串,char數組末尾總是有一個\0。它表示字符串的結尾。例如,假設你有這樣的:

char myText[] = "hello"; 

在這種情況下,數組的地方是這樣的:

 

    myText[0] = 'h'; 
    myText[1] = 'e'; 
    myText[2] = 'l'; 
    myText[3] = 'l'; 
    myText[4] = 'o'; 
    myText[5] = '\0'; 

但是,數組不'\0'終止。再舉一個例子:

int myArray[3] = {1, 2, 3}; 

根據您的規則,因爲數組有一個'\0'終止,這不是一個法律聲明,因爲我們只給出數組3個元素,而不是4,我們將需要4種元素包括一個'\0'。然而,這在C中是一個完全合法的陳述。很明顯,在數組中不需要用於的空間,只是在C字符串的末尾。

還要注意的是'\0'相當於整數,如Kninnug在評論中指出:

\0(空字符)不一樣的NULL指針。 \0是設置爲0的所有位,這將總是等於爲int 0

所以一個字節,在你的程序,你可以只同樣檢查:

if(nums[i] == 0) 

現在,讓我們證明你爲什麼得到你的輸出。

空字符不應該只在整個數組的末尾一次?

否。剩下的任何其他元素將被初始化爲零值。所以這就是爲什麼你看到你有輸出;不是num[0],num[1],num[2]num[10]的元素將被初始化爲零。既然你檢查\0(也0),那麼其他一切與沒有這些元素將是0


由於alk在評論中指出,空字符和空指針文字是不同的。在C字符串的末尾,您會看到空字符(NUL),即'/0'或0.但是,空指針字面量(NULL)不同。

+0

任何人都可以解釋倒票,所以我可以改善這個職位嗎? – iRove

+0

NUL(空字符的名稱)和NULL(空指針字面)是不同種類的動物。 – alk

+0

C- C-「string」是一個字符數組,其中至少有一個元素等於NUL,空字符(等於''\ 0''等於'0')。字符數組不一定是C-字符串。 – alk

0

NULL定義爲(無效*)0 - 它是零與通用PTR鑄造, 至極等於NULL字符的(\ 0)的ASCII碼 - 0

陣列不需要結束與任何特殊字符/數字。

串就需要使用特殊的字符來結束,原因很簡單,它可以讓功能至極運行在字符串「知道」裏的字符串結尾,例如:

char str[100] = {'h','e','l','l','o',0}; // same as {'h','e','l','l','o','\0'} 
printf("%s",str); 

打印: 你好

如果字符串中的最後一個字符不是NUL,它將在字符串(「hello」)後面打印95個垃圾字符,因爲數組大小爲100,編譯器無法知道字符串結束的位置。

儘管第6個單元格的零位在大多數編譯器中都以字符串結束,但您可以只設置「hello」字符串,它們將用零填充剩餘的單元格,所以在兩種情況下都可以。

+0

NUL(空字符的名稱)和NULL(空指針字面)是不同種類的動物。 – alk

+0

我沒有寫他們是同一件事.. –