模拟实现strcat函数时的一些小发现

在模拟实现strcpy函数时,代码如下:

//模拟实现strcpy函数
#include<stdio.h>
#include<assert.h>

char* my_strcpy(char* dest, const char* src)
{
    assert(dest && src);
    char* string = dest;
    while (*dest++ = *src++)
        ;
    return string;
}

int main()
{
    char arr1[] = "abcdef";
    char arr2[10] = { 0 };
    char* str = my_strcpy(arr2, arr1);
    printf("%s\n", str);//打印结果为:abcdef
    return 0;
}

我发现了循环内部写成*dest++ = *src++的好处,这样可以简洁高效的执行代码,那么我想在模拟实现strcat函数时,还能否这样写呢?

我们都知道strcpy函数和strcat函数非常相似,只不过strcat函数比strcpy函数多了一步找目标字符串中第一个\0的步骤。

我写的实现代码如下:

//模拟实现strcat函数
#include<stdio.h>
#include<assert.h>

char* my_strcat(char* dest, const char* src)
{
    assert(dest && src);
    char* string = dest;
    
    //找目标字符串中第一个\0
    while(*dest++)
        ;
    //拷贝
    while(*dest++ = *src++)
        ;
    return string;
}

int main()
{
    char arr1[20] = "Hello ";
    char arr2[] = "World!";
    char* str = my_strcat(arr1, arr2);
    printf("%s\n", str);
    return 0;
}

运行起来后发现结果并不正确,于是我开始调试。

在调试时我发现了问题,字符串追加不是应该在目标字符串\0处开始吗,这个程序就存在bug。

在经过调试修改之后,我发现使用前置++,对此时的结果的输出正确。具体代码如下:

//模拟实现strcat函数
#include<stdio.h>
#include<assert.h>

char* my_strcat(char* dest, const char* src)
{
    assert(dest && src);
    char* string = dest;
    
    //找目标字符串中第一个\0
    while(*++dest)
        ;
    //拷贝
    while(*dest++ = *src++)
        ;
    return string;
}

int main()
{
    char arr1[20] = "Hello ";
    char arr2[] = "World!";
    char* str = my_strcat(arr1, arr2);
    printf("%s\n", str);
    return 0;
}

 就当我认为已经正确时,我发现如果目标字符串第一个字符就是\0的话,这个程序又不正确了。

造成这个错误的原因是追加字符串时,找第一个\0的过程中,由于前置++的优先级要比*优先级高,所以是先++找下一个字符,这样首字符的\0就很轻松的被混过去了。

所以针对这个问题,我想了三种解决方法:

1、如果是后置++,在找到\0时,又被++了一次,这就使指针指向\0后面的字符了,所以可以在拷贝之前让指针--,具体代码如下:

//模拟实现strcat函数
#include<stdio.h>
#include<assert.h>

char* my_strcat(char* dest, const char* src)
{
    assert(dest && src);
    char* string = dest;

    //找目标字符串中第一个\0
    while (*dest++)
        ;
    dest--;//使指针--
    //拷贝
    while (*dest++ = *src++)
        ;
    return string;
}

int main()
{
    char arr1[20] = "\0Hello ";
    char arr2[] = "World!";
    char* str = my_strcat(arr1, arr2);
    printf("%s\n", str);//打印结果为:World!
    return 0;
}

2、如果是前置++,这就导致第一个字符如果是\0的话,是不能被找到的,所以解决方法可以是在找第一个\0之前先判断目标字符串中的第一个是不是\0,如果是则直接拷贝,不是就找第一个\0,具体代码如下:

//模拟实现strcat函数
#include<stdio.h>
#include<assert.h>

char* my_strcat(char* dest, const char* src)
{
    assert(dest && src);
    char* string = dest;

    //判断目标字符串第一个字符是不是\0
    if (*dest)
    {
        //找目标字符串中第一个\0
        while (*++dest)
            ;
    }
    //拷贝
    while (*dest++ = *src++)
        ;
    return string;
}

int main()
{
    char arr1[20] = "\0Hello ";
    char arr2[] = "World!";
    char* str = my_strcat(arr1, arr2);
    printf("%s\n", str);//打印结果为:World!
    return 0;
}

 3、第三种方法也就是最好理解的一种方法了,就是在找第一个\0时,将判断和++分开,具体代码如下:

//模拟实现strcat函数
#include<stdio.h>
#include<assert.h>

char* my_strcat(char* dest, const char* src)
{
    assert(dest && src);
    char* string = dest;

    //直接把判断和++分开
    while (*dest != '\0')
        dest++;
    //拷贝
    while (*dest++ = *src++)
        ;
    return string;
}

int main()
{
    char arr1[20] = "\0Hello ";
    char arr2[] = "World!";
    char* str = my_strcat(arr1, arr2);
    printf("%s\n", str);//打印结果为:World!
    return 0;
}

其实这三种写法并没有太大的差别,只是我在写代码时想到的解决问题的方法。但是在我看来,第三种方法是最好的,不仅方便阅读理解,还不容易出现bug。

 以上就是我这次的分享了,写的不好,请多担待!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值