在模拟实现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。
以上就是我这次的分享了,写的不好,请多担待!