C 编程中的数组是否以 NULL 结尾?

Do arrays end with NULL in C programming?

提问人:Pranav Vasishta 提问时间:12/26/2022 最后编辑:user3840170Pranav Vasishta 更新时间:12/26/2022 访问量:408

问:

我是 C 语言的初学者,我被要求在不使用运算符的情况下计算数组的大小。所以我尝试了这段代码,但它只适用于奇数个元素。所有数组都像字符串一样以 NULL 结尾。sizeof

#include <stdio.h>
void main()
{
    int a[] = {1,2,3,4,5,6,7,8,9};
    int size = 0;
    for (int i = 0; a[i] != '\0'; i++)
    {
        size++;
    }
    printf("size=%d\n", size);
}
数组 c null

评论

0赞 Harith 12/26/2022
这回答了你的问题吗?这段代码如何在不使用 sizeof( ) 的情况下确定数组大小?
2赞 H.S. 12/26/2022
请注意,和是不一样的。'\0'NULL
1赞 Clifford 12/26/2022
不像字符串。字符串可能包含在 char 数组中,但 nul 并不表示数组的末尾,它表示字符串的末尾,可能更短。认为字符串数组以 nul 结尾,字符串以 nul 结尾,不一定是包含数组,它只是一个数组,这是一种误解。字符串不是 C 中的数据类型,它们是一种约定
1赞 Clifford 12/26/2022
null 字符的 ASCII 助记符是 。C 宏引用一个空指针,最好不要将两者混淆。NULNULL

答:

5赞 Sourav Ghosh 12/26/2022 #1

不,通常,数组没有默认的哨兵字符。

作为一种特殊情况,以 null 终止符(ASCII 值 0)结尾的数组称为字符串。但是,这是一个特例,而不是标准。

评论

0赞 Pranav Vasishta 12/26/2022
此代码适用于奇数而不是偶数的原因可能是什么?
0赞 Sourav Ghosh 12/26/2022
未定义的行为。您正在读取代码中的有效内存。
0赞 Clifford 12/26/2022
字符串以 nul 结尾,而不是以包含数组结尾。从这个意义上说,没有“特例”。数组可以比字符串长,并且数组的末尾不需要包含 nul。
0赞 Sourav Ghosh 12/26/2022
除非,它是在声明和定义时初始化的。然后,我们可以确定数组末尾包含 null。右?
0赞 H.S. 12/26/2022 #2

>所以我尝试了这段代码,但它只适用于奇数个元素。

尝试使用此数组的代码 -

int a[] = {1,2,0,4,5,6,7,8,9}; 
               ^
               |
          3 replaced with 0

你会发现输出将是,为什么?
由于 for 循环条件 - 。
size=2a[i] != '\0'

那么,当循环条件达到 - 时会发生什么?
这是整数字符常量,其类型为 。它与 相同。当 为 时,条件变为 并且循环退出。
fora[i] != '\0''\0'int0a[i]0false

在您的程序中,数组的任何元素都没有值,并且循环不断迭代,因为条件会导致数组的每个元素,并且您的程序最终会访问超出其大小的数组,这会导致未定义的行为。a0fortrue

> 是否所有数组都像字符串一样以 NULL 结尾。

答案是否定的。在语言中,数组和字符串都不以 结尾,相反,字符串实际上是以第一个 null 字符结尾并包含第一个 null 字符的一维字符数组。CNULL'\0'

要在不使用 的情况下计算数组的大小,您需要的是数组消耗的总字节数和数组元素类型的大小(以字节为单位)。一旦你有了这些信息,你就可以简单地将总字节数除以数组元素的大小。sizeof

#include <stdio.h>
#include <stddef.h>

int main (void) {
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    ptrdiff_t size = ((char *)(&a + 1) - (char *)&a) / ((char *)(a + 1) - (char *)a);

    printf("size = %td\n", size);
    return 0;
}

输出:

# ./a.out
size = 9

附加:

'\0'并且是不一样的。NULL