C数组和空字节

时间:2016-08-13 21:39:34

标签: c arrays null int

我有一个问题,可以更好地了解数组和nullbytes如何在C中工作。

假设我有一个包含13个单元格的int数组。 让我们说我希望单元格编号:1,2,3和10有一个值。保留的其他默认值会自动将nullchar \ 0作为值?

我对\ 0的理解是,nullbyte总是在数组的末尾,它的功能是告诉程序数组的结束位置。但似乎是错误的

我写了一个简单的编程来验证,似乎就是这样:

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

找到null char!在位置:3

找到null char!在位置:4

找到null char!在位置:5

找到null char!在位置:6

找到null char!在位置:7

找到null char!在位置:8

找到null char!在位置:9

元素:69位于位置:10个int数组

找到null char!在位置:11

找到null char!在位置:12

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

那么为什么默认单元格设置为\ 0值?而不是留空例如?

在整个数组的末尾,null char是不是只有一次? 感谢

3 个答案:

答案 0 :(得分:3)

C中没有要求数组最后需要\0。只有C 字符串(通常具有charwchar_t或其他字符类型)才需要NUL终止符。在C字符串中,\0字节也不必位于包含它的数组的末尾,但它必须位于字符串部分的末尾。在数组中的任何位置都有0是完全有效的。但是如果该数组用作字符串,则标准C字符串函数将使用最低索引解释0以表示字符串的结尾。

使用初始化程序(nums)在C中声明变量({1,2,3})时

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

初始值设定项中未提及的所有索引(3到12)的值都初始化为0。不可能有空的&#39;数组中的单元格。所有单元格都有一个值,由程序(mer)决定哪些值为空。

答案 1 :(得分:1)

C类型对应于内存,而内存没有&#34;空&#34;的真实概念。有些语言可以制作所有(或几乎)所有(或几乎)空的&#34;把一些&#34;空的&#34;常量(例如,Python有None),但C不允许这样做。不允许它的一个原因是它迫使你对空状态有一个特殊的通用模式,这具有低级别的影响。例如,一个字符可以包含0到255之间的任何值。这是因为字符占用8位。如果你还想要一个空状态而不牺牲字符的可能值,那么你至少还需要一个比特,因为其他8个比特可以出于合法的原因使用,而且由于很多原因这是不可取的。 / p>

对于您的数组,您使用的初始化语法将每个未指定的元素设置为零。如果你写:

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

然后每个元素都有一个值(注意它最后没有空字节,因为数组最后不需要有一个空字节 - 但是,如果你将它们用作字符串,那么他们非常应该)。如果你写:

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

元素0和1具有指定值,但是2和3不具有,并且使用此语法C将假设您想要将它们设为零。另一方面,如果你写:

char foo[4];

您没有为任何元素分配任何值,在这种情况下,C根本不会初始化数组。从中读取它将是未定义的行为;实际上,通常情况下,元素将采用先前存在于其内存位置的任何事物的值。

答案 2 :(得分:-1)

首先,您将C字符串与常规数组混淆。对于字符串,\0数组末尾始终有char。它表示字符串的结尾。例如,假设你有这个:

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个元素来包含{{1} 1}}。但是,这是C中完全合法的声明。很明显,数组中不需要'\0'的空间,只是在C字符串的末尾。

另请注意,'\0'等同于注释中指出的Kninnug整数:

  

'\0'(空字符)与NULL指针不同。 \0是一个字节,所有位都设置为0,总是比较等于int 0。

因此,在您的计划中,您可以同样检查是否:

\0

现在,让我们来证明你获得输出的原因。

  

在整个数组的末尾,null char是不是只有一次?

没有。留空的任何其他元素将使用零值初始化。这就是为什么你看到你拥有的输出;非if(nums[i] == 0) num[0]num[1]num[2]的元素将初始化为零。由于您正在检查num[10](也是\0),因此其他所有不包含这些元素的内容都将为0。

在注释中指出alk,空字符和空指针文字是不同的。在C字符串的末尾,您会看到空字符(NUL),即0或0.但是,空指针文字('/0')是不同的。