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)没有变化?

解决方法

代码的含义是什么:dest + strlen(dest)

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

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

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

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

sizeof 不会改变,因为它是在编译时确定的,所以它总是显示相同的值。

,

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

我认为您是指此声明中的函数名称 strcat 而不是 STRCAT

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

此函数旨在处理以零字符 '\0' 结尾的字符序列的字符串。

函数 strlen 返回字符串中终止零字符 '\0'; 之前的字符数。

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

例如,如果你有一个像这样声明的字符数组

char dest[3] = { '1','0' };

和声明的源数组

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

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

结果 dest + strlen( dest ) 指向数组 dest 的第二个字符,即零字符 '0'。还有这个电话

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

将从该位置开始,将数组src中存储的字符串的字符复制到数组dest中,得到如下数组dest内容

{ '1','2','\0' }

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

char s[10]= "123456789"

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

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

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

在你的程序中数组 str

char str[10] = " 123456789";

不包含字符串,因为它没有空间来容纳用作初始化器的字符串文字的(第十一个)终止零字符。

另一方面,数组 s 没有空间可以将另一个字符串附加到其尾部。

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

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

#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 )