strcat()源码解释

explanation of the souce code of strcat()

    char *
STRCAT(char *dest, const char *src)
{
  strcpy(dest + strlen(dest), src);
  return dest;
}

代码 :dest + strlen(dest) 是什么意思? 当我使用如下代码时:

#include <stdio.h>
#include <string.h>
void main()
{
    char s[10]= "123456789";
    char str[10] = " 123456789";
    strcat(s,str);
    printf("%s\n",s);
    printf("%d",sizeof(s));
    
}

为什么字符串s没有溢出,sizeof(s)没有变化?

what's the meaning of the code :dest + strlen(dest)

它计算指向 dest 末尾的指针,因为使用 strcat 您想将第二个字符串附加到第一个字符串的末尾。它类似于:

size_t l = strlen(dest);
char *p = &dest[l];  // dest + l pointer arithmetic.
strcpy(p, src);

why the string s didn't overflow and the sizeof(s) did not change?

s 溢出,因为在 strcat 完成后,您的字符串现在有 20 个字符长,而它只能容纳 10 个字符。这会调用 undefined behavior.

sizeof不会变,因为编译时就确定了,所以会一直显示相同的值。

strcatSTRCAT 是两个不同的函数。:)

我想你在这个声明中指的是函数名 strcat 而不是 STRCAT

    char *
strcat(char *dest, const char *src)
{
  strcpy(dest + strlen(dest), src);
  return dest;
}

此函数旨在处理以零字符结尾的字符序列的字符串 '[=24=]'

函数strlen returns 字符串中终止零字符前的字符数'[=26=]';

所以表达式dest + strlen(dest)指向目标字符数组中包含的字符串的终止零字符'[=24=]'。因此函数 strcat 可以将源字符串附加到存储在目标数组中的字符串,从终止零开始。

例如,如果您有一个声明为

的字符数组
char dest[3] = { '1', '0' };

源数组声明为

char src[2] = { '2', '0' };

对于数组 dest,函数 strlen( dest ) 将 return 值 1

因此 dest + strlen( dest ) 指向数组 dest 的第二个字符,即零字符 '0'。而这个电话

strcpy(dest + strlen(dest), src);

会将数组src中存储的字符串的字符复制到数组dest中以此位置开始,得到数组dest

的如下内容
{ '1', '2', '[=14=]' }

在您的程序中,表达式 sizeof( s ) 给出声明数组 s 的元素数

char s[10]= "123456789"

10。该数组声明中指定的值不依赖于数组将具有的内容,而是在编译时计算的。

注意由运算符 sizeof 编辑的值 return 的类型为 size_t。因此,要使用函数 printf 输出它们,您必须使用转换说明符 zu。例如

printf("%zu\n",sizeof(s));

在你的程序中数组str

char str[10] = " 123456789";

不包含字符串,因为它没有 space 来容纳用作初始值设定项的字符串文字的(第十一个)终止零字符。

另一方面,数组 s 没有 space 可以在其尾部附加另一个字符串。

所以你的程序有未定义的行为。

一个有效的程序可能看起来像

#include <stdio.h>
#include <string.h>

int main( void )
{
    char str[] = " 123456789";
    char s[10 + sizeof( str ) - 1] = "123456789";

    strcat( s, str );

    printf( "%s\n", s);

    printf( "%zu\n", strlen( s ) );

    printf( "%zu\n", sizeof( s ) );
}

注意,根据 C 标准,不带参数的函数 main 应声明为

int main( void )