指向char,不同术语的指针

时间:2016-06-20 11:21:33

标签: c arrays string language-lawyer

我多次使用strncat,但现在只检查标准中的正式定义:

#include <string.h>
char *strncat(char * restrict s1,
     const char * restrict s2,
     size_t n);
  

strncat函数从s2指向的数组到s1指向的字符串末尾追加不超过n个字符(空字符及其后面的字符不会被追加)。 s2的初始字符将覆盖s1末尾的空字符。终止空字符始终附加到结果中。

通常,我会将s1s2简单地视为char的指针。但正如所看到的,该标准对它们的要求不同:

  • s1
  • 指向的字符串
  • s2
  • 指向的数组

s1s2之间的唯一区别是const限定符 - 这就是为什么一个被称为数组而另一个被称为字符串

此外,在脚注中:

  

因此,s1指向的数组中可以结束的最大字符数是strlen(s1)+ n + 1.

所以这里他们以不同的方式引用s1s1指向的数组(不是字符串)

这些不同的方式调用s1s2是否有任何暗示?

3 个答案:

答案 0 :(得分:16)

  

s1和s2之间的唯一区别是const限定符

不,不一定。

  • 目标数组s1 必须已经以空值终止。因此,它可以安全地称为字符串

    引用C11,章节§7.1.1/ p1,术语定义

      

    string 是由第一个null终止并包含第一个null的连续字符序列   字符。 [...]

  • 但是,对于源数组s2,如果给定大小n小于实际长度,则null终止不是必须数组。所以,必须不是字符串,总是。

所以, TL; DR - 目的地数组总是字符串(因此可以互换使用)但是没有这样的保证对于源数组。

另外,为了突出显示用法中的差异,我们将其与strcat()的描述进行比较,s2具有相似的语法,减去大小。因此,两个参数都需要以null结尾,因为没有其他方法可以让函数确定 source 数组strcat的结尾。因此,请注意那里的措辞(强调我的),来自章节§7.24.3.1

  

s2函数附加s1 指向的字符串的副本(包括   终止空字符)到s2 指向的字符串的末尾。最初的角色   s1的覆盖范围覆盖 SELECT * FROM `Contacts` WHERE `Zona` = '1' AND `Responsable` = '9' AND `AllowComercialVisit` = 'Call_Again' -- the problem are OR's -- OR `AllowComercialVisit` = 'Busy' OR `AllowComercialVisit` = 'Not_answered' -- the problem are OR's -- AND `DateRecall` <= '2016-06-20 13:04:52' AND `DateRecall` >= '2016-06-20 12:39:52' ORDER BY `DateRecall` ASC LIMIT 1 末尾的空字符。如果在之间进行复制   重叠的对象,行为未定义。

这里,两个数组必须是字符串,因此是用法。

答案 1 :(得分:4)

在C中,字符串NUL - 已终止,其中数组不是(必需)。这就是这个函数采用n参数的原因;因为s2不一定是NUL - 已终止。

答案 2 :(得分:2)

数组是存储区域。 string 是一个特殊的字符序列(以空终止符结尾),可以存储在数组中。

char数组在任何特定时间都可能包含或不包含字符串。

(尽管已经有几个答案,我仍在发帖,因为其他答案并未使容器包含的关系明确。)

使用strncat函数,第一个参数必须指向包含字符串的数组中的字符(我们说“指向字符串”);但由于第二个参数可能是长度计数的,因此它可以指向数组中不包含字符串的字符。