模拟实现strcpy

本文详细介绍了C语言中strcpy函数的作用及基本用法,并逐步展示了如何模拟实现strcpy,包括基础实现、过程优化、安全性检查以及返回值优化。在优化过程中,强调了const关键字的重要性以及空指针安全性的处理,最后给出了完整版的优化实现。
摘要由CSDN通过智能技术生成

首先我们先来认识一下strcpy这个函数,该函数的作用是将字符串1的内容拷贝到字符串2中,
声明方式为

char * strcpy ( char * destination, const char * source );

其中destination所指向的地址是上文中的字符串2,source是字符串1上的地址
模拟strcpy前我们先来熟悉一下strcpy的用法

int main()
{
	char str[20] = { 0 };
	strcpy(str, "hello");
	printf("%s\n", str);
	return 0;
}

代码打印出的结果就是hello
那么下面我们来模拟实现strcpy

一、最基本的思想

void my_strcpy(char* dest, char* src)
{
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;
}

该代码中我们将src中每一个字符利用循环体的结构分别拷贝给dest,循环体用src != ‘\0’作为条件语句,当src指向’\0’的时候循环跳出,此时’\0’并没有被拷贝入dest,因此我们在循环跳出的时候需要追加一个*dest = *src。

二、实现过程优化

我们通过最基本的代码了解了strcpy的实现过程,下面就要对最初的代码进行优化
优化代码如下

void my_strcpy(char* dest, char* src)
{
	while (*src != '\0')
	{
		*dest++ = *src++;//hello的拷贝
	}
	*dest = *src;//\0的拷贝
}

该代码在实现的过程中将循环体内部代码实现进行了一个优化,后置++表示先赋值再++,即在循环体内部我们先将src指向字符的值赋给dest指向的字符,然后src和dest再向后移动一个字节,这与我们最初的代码的实现过程完全一致。

三、实现过程进一步优化

void my_strcpy(char* dest, const char* src)
{
	while (*dest++ = *src++)
    {
          ;
    }

}

(1)当*dest++ = *src++作为一个判断条件时,这个式子的值为该次src拷贝给dest的字符的值,因此我们再来看这个循环,在src指向‘\0’之前,每一次的循环中条件语句的结果都是一个字符,为真,所以进入循环,并且条件语句在给出值的同时也让src和dest两个指针向后各自移动一个字节,保证拷贝字符的顺利进行,当条件语句给出的值为‘\0’时,’\0’的asc码值为0,说明条件语句为假,循环跳出,此时’\0’已经赋给了dest,故不需要额外加一次赋值。
(2)此外,在此次修改中我们在函数的形src之前加上了一个const,目的是为了防止使用者在使用strcpy函数时将dest和src两个实参输反了,例如:

my_strcpy(dest,src)//正确写法
my_strcpy(sre,dest)//使用者写法

使用者的写法会带来很多问题,最直接的一个问题就是会导致结果出错(本来想把1拷给2,最后结果把2拷给了1),其次就是因为两个字符串的长度很可能不一样,反过来拷贝的话会出现将长的字符串拷贝到短的字符串中,结果会导致程序崩溃。但如果我们在src前面加上const,当程序按照使用者的写法走起来时系统会在my_strcpy函数使用的那一行报错,提示使用者两个位置输反了,从而避免错误结果的产生。
从另一个角度来说,strcpy的本质就是将src的内容拷贝进dest指向的空间中,dest内容改变而src内容不变,所以基于这个角度,我们也应该给形参src前面加上一个const来保证src内容不被改变。

四、安全性优化

#include《assert.h>
void my_strcpy(char* dest, const char* src)
{
	assert(src != NULL);
	assert(dest != NULL);
	while(*dest++=*src++)
	{
		;
	}
 }

在这段代码中我们断言src和dest不为空指针,因为空指针时不能进行解引用操作的,强行操作会使代码无法运行,而我们断言之后,如果src是空指针的话,在程序运行的过程中会反馈断言失败,我们可以很快地发现问题并解决问题。

五、返回值优化

最后,对比我们现在写的strcpy和库函数中的strcpy,我们发现这二者的返回值不同经过查找我们发现的库函数strcpy的返回值
翻译过来,strcpy返回的是目标空间的起始地址,这样做的话可以更加便于我们查看修改后的字符串,因此我们给出strcpy的最后一次优化

#include《assert.h>
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(src != NULL);
	assert(dest != NULL);
	while(*dest++ = *src++)
	{
		;
	}
	return ret;
 }

到这里我们strcpy的模拟实现就全部结束啦,小编水平有限,编写过程中难免出错,如有错误欢迎读者及时指正!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值