模拟strcpy库函数的实现(超详细)

⭐博客主页:️CS semi主页
⭐欢迎关注:点赞收藏+留言
⭐系列专栏:C语言初阶
⭐代码仓库:C Advanced
家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我创作最大的动力,欢迎友友们私信提问,家人们不要忘记点赞收藏+关注哦!!!

文章目录

  • 前言
  • 一、简介
    • 1.认识strcpy
    • 2.应用strcpy
    • 3.监视分析
  • 二、模拟实现strcpy
    • 1.初步实现
    • 2.输入空指针
    • 3.assert
    • 4.这阶段完整代码
  • 三、返回值
    • 1.返回类型
    • 2.const
  • 四、完整代码
  • 总结


前言

strcpy函数其实大家并不陌生,但是每次用的时候要么就复制到字符串的地方不对,要么就出现错误,那到底该怎么用这个函数呢?接下来我将详细给大家讲解strcpy这个函数的本质和用法!


一、简介

1.认识strcpy

再认识这个函数之前,我先放一张图片供大家理解一下:
模拟strcpy库函数的实现(超详细)_第1张图片
在MSDN中查一下这个函数,发现是从后面的数组复制一份复制到前面的数组,那当然,大家伙可能会问了,为什么有一个const被圈出来了,这个const很熟悉呀,之前见到过了,大家伙继续往后看,在文中我会跟大家详细解说一下这个const与指针配套起来的用法。

2.应用strcpy

先带大家看一看运用一下strcpy的奇效。

#include
#include
int main() {
	char arr1[20] = "****************";
	char arr2[] = "hello";
	strcpy(arr1, arr2);
	printf("%s\n", arr1);	
	return 0;
}

模拟strcpy库函数的实现(超详细)_第2张图片
看,运用了这个函数以后感觉是在是太方便了,能把arr2中的“hello\0”全部复制到arr1[20]里面去,唉,大家可能会问了,屏幕上显示的是hello啊,没有那个’\0’,大家继续往下面看,就立马能够理解了。

3.监视分析

先上几张图片让大家理解理解。

1.将*赋到arr1数组中。

模拟strcpy库函数的实现(超详细)_第3张图片

2.将hello+’0’赋到arr2数组中。

模拟strcpy库函数的实现(超详细)_第4张图片

3.进行复制的操作。

模拟strcpy库函数的实现(超详细)_第5张图片

4.原理图

模拟strcpy库函数的实现(超详细)_第6张图片

利用监视器看strcpy函数能够看到它的本质就是将后面数组里面的字符串+‘、0’拷贝到前面的数组中,但是为什么会有\0呢,这个很简单,arr[]={a,b,c,d}与arr[]="abc"是有本质的区别的,后者多一个\0,大家可以去看看我以后写的关于数组的区分的博客哦!


二、模拟实现strcpy

1.初步实现

先上个代码:

代码1:这个代码很好理解,就先取数组的首地址并交换再往后加加,直到最后一个元素进行交换完退出循环。

#include
//#include
void my_strcpy(char* dest, char* src) {
	while (*src != '\0'){
		*dest++ = *src++;
	}           
	*dest = *src;   //拷贝\0
}
int main() {
	char arr1[20] = "****************";
	char arr2[] = "hello";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

代码2:这个代码可以把\0直接打印出来,不需要最后一步加上交换一次\0。

#include
//#include
void my_strcpy(char* dest, char* src) {
	while (*dest++ = *src++) {
		;
	}           
}
int main() {
	char arr1[20] = "****************";
	char arr2[] = "hello";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

但这代码实现的看似没什么问题,可是也隐藏着一个很大的问题,数组是我已经定义好了的,但是,如果是在主函数里面输入NULL(空指针)呢?那让我们先来看看。

2.输入空指针

模拟strcpy库函数的实现(超详细)_第7张图片
输入空指针后,编译器立马就报错了,所以,这是肯定不行的!那怎么解决呢?接下来上一串代码!

子函数里加了先判断输入的两个指针元素存不存在空指针,有空指针那就不进行后续操作。

#include
//#include
void my_strcpy(char* dest, char* src) {
	if (src == NULL || dest == NULL)
	{
		return;
	}
	while (*dest++ = *src++) {
		;
	}           
}
int main() {
	char arr1[20] = "****************";
	char* p = NULL;
	my_strcpy(arr1, p);
	printf("%s\n", arr1);
	return 0;
}


大家想一个问题,如果一个程序员喝了点小酒醉了,只看到了这个程序可以直接运行,很开心的到老板那里邀功,老板说,你这做的啥!为什么导致程序员犯错了呢,很简单,机器没有报错,程序员以为是对的,所以,接下来引进一个新的函数为“断言’(assert)函数。

3.assert

assert中可以放一个表达式,表达式的结果如果为假,就报错,如果为真那就正常运行

实现代码:

#include
#include
//#include
void my_strcpy(char* dest, char* src) {
	/*if (src == NULL || dest == NULL)
	{
		return;
	}*/
	assert(src != NULL);
	assert(dest != NULL);

	while (*dest++ = *src++) {
		;
	}           
}
int main() {
	char arr1[20] = "****************";
	char* p = NULL;
	my_strcpy(arr1, p);
	printf("%s\n", arr1);
	return 0;
}

模拟strcpy库函数的实现(超详细)_第8张图片

很明显,这个程序报错了,而且给你标注了哪里出错了,是不是很方便快捷,当然,头文件不要漏掉。

4.这阶段完整代码

这一阶段的完整代码如下:

#include
#include
//#include
void my_strcpy(char* dest, char* src)
{
	assert(dest && src);//断言指针的有效性
	while (*dest++ = *src++)
	{
		;
	}
}

int main()
{
	//strcpy - 字符串拷贝
	//char arr1[20] = "xxxxxxxxxxx";
	//char arr2[] =   "hello";
	//my_strcpy(arr1, arr2);
	//printf("%s\n", arr1);
	char arr3[20] = {0};
	char* p = NULL;
	my_strcpy(arr3, p);

	return 0;
}

三、返回值

大家如果细心看那张strcpy的图,会发现两个小问题,这strcpy是有返回值的呀,还有那个const怎么一直没有解决呢?接下来,我们开始解决问题!

1.返回类型

模拟strcpy库函数的实现(超详细)_第9张图片
那接下来修改一下这个代码吧!

#include
#include
//#include
char* my_strcpy(char* dest, char* src)
{
	assert(dest && src);
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[20] = "*************";
	char arr2[] = "hello";
	printf("%s\n", my_strcpy(arr1, arr2));  //链式访问
	return 0;
}

这样就有返回值了!

2.const

接下来到了最激动人心的时刻,久久困扰的const该怎么做呢?下面且听我分析。

大家先来看看这张图片,生动形象的解释了const。

模拟strcpy库函数的实现(超详细)_第10张图片

情况一:const 在的左边:const int p 与 int const * p 一样哦~

//const放在* 的左边,const修饰的是指针指向的内容,表示指针指向的内容,不能通过指针来改变了; 但是指针变量本身可以修改
int num = 0;
int n = 1000;
const int* p = #
 *p = 20;//err
 p = &n;//ok

情况二:const 在*的右边:int * const p

 const放在*的右边,const修饰的指针变量本身,表示指针变量本身的内容不能被修改,但是指针指向的内容,可以通过指针来改变。
int* const p = #
*p = 20;//ok
 p = &n;//err

到这里就完美解决了strcpy函数的问题。


四、完整代码

#include
#include
//#include
char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[20] = "*************";
	char arr2[] = "hello";
	printf("%s\n", my_strcpy(arr1, arr2));  //链式访问
	return 0;
}

总结

模拟strcpy函数让我们大家深刻理解了这个函数的原理以及用法,最好的一点是让我们了解了assert和const的使用,一举三得!!!!

客官都阅读到这边了,码字不易,求个三连支持!

你可能感兴趣的:(C语言初阶,数据结构,算法,c++,开发语言,c语言)