指向char,不同术语的指针

art*_*rtm 12 c arrays string language-lawyer

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

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

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

通常我会想到s1s2简单地指向char.但正如所看到的,该标准对它们的要求不同:

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

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

而且,在脚注中:

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

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

有没有的调用这些不同方式的任何含义s1s2

Sou*_*osh 16

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

不,不一定.

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

    引用C11,第7.1.1节/第1章,术语定义

    是由封端的字符的连续序列,并且包括第一个空字符.[...]

  • 但是,对于源数组s2,如果给定的大小小于数组的实际长度,则无需终止空终止n.因此,它一定不会是一个字符串,始终.

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


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

strcat功能追加的副本串指向s2(包括终止空字符)到的端部指向的字符串s1.最初的字符s2覆盖了结尾处的空字符s1.如果在重叠的对象之间进行复制,则行为未定义.

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