C 何时将\0添加到数组中

C 何时将\0添加到数组中,c,arrays,C,Arrays,对于C中的字符串或数组,我无法确定何时设置“\0” 示例: 如果为了避免缓冲区溢出,我使用char tab[20]定义了一个数组,那么我应该在什么时候添加“\0” tab[20] = 0; 或 对于定义为char tab[20]的数组,tab[20]不是有效的成员(或者,换句话说,20不是有效的索引)。记住,C数组使用基于0的索引 您只能访问从0到size-1的索引,即从0到19的索引,在这种情况下,您必须在最后一个有效位置添加索引19 也就是说,在最后一个成员中始终添加null终止符不是强

对于C中的字符串或数组,我无法确定何时设置“\0”

示例: 如果为了避免缓冲区溢出,我使用
char tab[20]
定义了一个数组,那么我应该在什么时候添加“\0”

tab[20] = 0; 


对于定义为
char tab[20]
的数组,
tab[20]
不是有效的成员(或者,换句话说,20不是有效的索引)。记住,C数组使用基于0的索引

您只能访问从0到size-1的索引,即从0到19的索引,在这种情况下,您必须在最后一个有效位置添加索引19

也就是说,在最后一个成员中始终添加null终止符不是强制性的。根据用法,您需要将null终止符放在最后一个有效元素之后。在本例中,索引的最大值为19

考虑以下示例:

char arr[20]; // local variable, not initialized , elements holds indeterminate value

arr[0] = 'H'
arr[1] = 'E'
arr[2] = 'L'
arr[3] = 'L'
arr[4] = 'O'
在这种情况下,要将
arr
用作字符串,需要将空终止符置于
arr[5]

但是,对于以下情况

arr[0] = 'H'
arr[1] = 'E'
. . . 
arr[18] = 'E'
您需要将其放入
arr[19]
,但仅此而已。您的数组不能再容纳任何值,19是允许您自由访问的最后一个索引。

如果您写入

char tab[20];
然后,
tab[0]
tab[19]
都有效

因此,为了保证C字符串函数不会溢出缓冲区,您应该编写

tab[19] = 0;
或者,您可以使用将数组中的所有元素初始化为0

char tab[20] = {0};

请注意,您可以读取指针
选项卡+20
,但不允许取消对它的引用。

缓冲区溢出取决于您使用缓冲区的方式。例如,如果您调用一个函数,该函数计划将40个字符放入20个字符的缓冲区中,那么不管您是否在最后预填充了\0个字符,最终肯定会导致缓冲区溢出

因此,经验法则:

  • 将缓冲区用作参数后,始终传递指向缓冲区的指针和缓冲区的长度。调用的函数必须遵守您提供的长度

  • 如果被调用函数需要一个特殊字符作为缓冲区结束标记(而不是缓冲区长度),则必须将其置于函数调用之前。不同的函数可能需要不同的特殊字符、\0或$或其他


当您使用与“\0”相关的一些高级信息时:

  • 预定义字符串库因为它们需要以“\0”结尾的字符数组
  • 缓冲区有效性(缓冲区结束):将字符串从一个实体解析到另一个实体时
  • 人们使用此:当您的代码需要与另一个代码合并时,您可能需要使用它

  • 对于任何数组,索引的有效范围是什么?有效范围是从0到(在我的例子中)19。那么,如果使用
    20
    作为索引,您认为会发生什么?请记住,字符数组与任何其他数组都没有什么不同。通常,如果我需要声明一个数组来存储20个项目,我会像
    tab[20+1]
    @FrankAK那样执行。如果您的“项目”不是字符串的字符,则无需添加额外的字节。我不会说您能够“读取”
    tab+20
    ,任何一个可能是“计算”:不,读取指针的值就足够了;i、 你可以写
    char*p=tab+20NULL
    0
    在概念上是不一样的,但是在C中, null 可以表示为整数零(并且在C++中,它必须是)。它在适当的上下文中转换为指针(特别是空指针),但打开它是一种十足的迂腐。事实上,你的建议在Q+A的水平上是最合适的:考虑<代码> null >代码>与字符或整数不同。
    char tab[20] = {0};