strcpy和strncpy的使用以及strcpy的模拟实现(三种方法)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: strcpy和strncpy的使用以及strcpy的模拟实现(三种方法)

前言:Hello!大家好,我是@每天都要敲代码;上一讲对于strlen库函数的使用和三种模拟实现方法相信大家都很熟悉了,strlen库函数是用来求字符串的长度,遇到'\0'终止;所需头文件是<string.h>;如果还没掌握的小伙伴可以重新复习一下:strlen库函数的使用和模拟实现<传送门>一下。这一期,我们来一起学习一下strcpy和strncpy的使用以及strcpy的模拟实现!!!

e78579794d854b768f6c659cb2db91ea.jpg


1.strcpy的使用:


   对于strcpy的使用相信大家都很熟悉了, strcpy是长度不受限制的字符串函数;参数只有两个,strcpy(dest,src);意思是把src里面得内容拷贝到dest里面,下面我们直接上代码:


aa9f63c74b6a4c5eaaa7ecf1ab9993a5.png


上面代码就是把arr2数组里的内容拷贝到arr1里面,并且我们给arr1数组足够的大小,确保arr2数组里的的内容能全部拷贝过来;我们打印arr1数组里面的数据,运行结果如下 :

9318f26cd3774b48b8274f54955ae07e.png


2.strncpy的使用:


对于strncpy的使用大家可能就很少见了; strncpy是长度受限制的字符串函数;参数只有三个,strcpy(dest,src,n);意思是把src里面得前n个字节的数据内容拷贝到dest里面,下面我们直接上代码:



034e7e4ad1474ed8965b456b84519bb6.png


上面代码就是把arr2数组里的前4个字节的内容拷贝到arr1里面,并且我们给arr1数组足够的大小,确保arr2数组里的的内容能拷贝过来;同时我们也可以自己拷贝自己;我们打印arr1数组里面的数据,运行结果如下 :


d4fa455eebf94a48a546458062b92d32.png


3.strcpy的模拟实现

方法1:


a9ee1ba169f54b7fb5f4b28bc2cb8cd6.png


解析:

我们来解析一下这个代码:


1.首先对于指针src我们加上了const,为什么呢?因为我们只是拷贝src指针里面的内容到dest,并不改变它,所以我们加上const修饰就更加的安全。


2.之后我们需要assert断言一下。


3.核心代码就需要我们思考一下,其实它和strlen的模拟实现很像,都是字符串嘛!我们还是找src字符串的\0,找不到就一直把src里面的内容赋值给dest就可以啦!


4.那么循环外面怎么又有一个*dest = *src呢?当然是把src里面的\0也拷贝进去啦!


当然,注释掉的三句代码,也可以用下面一句代码代替,他们本质上是一样的!!!


方法2:

a6ffb5fe9b764d8c9a7e328ab8fabc97.png


解析:


第二种方法实际上是第一种方法的优化,方法1我们还要单独把\0拿出来进行拷贝,那我们能不能在循环内部就完成所有的拷贝呢?当然是可以的,我们直接把循环条件改一下,*dest++ = *src++,在src遇到\0之前都是赋值操作,直到src遇到\0以后,相当于*dest++ = \0;咦,这不就是循环跳出来的条件,while循环遇到0就结束循环啊!所以此时不仅能刚好跳出循环,还能把\0也能赋值过去。最终我们循环里的内容什么都不需要执行,直接 “;” 就行啦!


方法3:

9147c07b68f94c1f851691cd98dbd474.png

解析:

为了让代码更加的优化,我们不妨用MSDN去搜索一下strcpy函数的使用:


char *strcpy( char *dest, const char *src );这好像和我们模拟实现的不太一样啊,我们模拟用的是void没有返回值,这里却用的确实char*返回的是一个char类型的指针;所以我们不妨在思考一下:在定义一个指针(暂定为start),指向dest的首地址,记住它的起始位置,在dest++的过程中,start确不会变,指针指向首元素的地址,到时候返回start这个指针不就好了嘛!!!最终的打印也会根据起始地址start打印,遇到\0终止。


每日一题


今天给兄弟们补充一道因为越界访问造成的死循环;我们一起看一下下面代码运算的结果:


50e8eb7120cb453d9fafbfe15e7514d0.png


解析:


首先是肯定越界访问了,但是死循环是怎么来的呢? 先创建的i变量,优先使用高地址;之后创建数组,数组是从低地址到高地址;当我们越界访问时,就有可能使得越界访问的数组与变量i的地址相同;我们又定义arr[i]=0;当arr[12]=0,最终也会使得变量i的值增加着增加着也变成0;最终造成死循环,我们通过调试发现在i=12时,i又立刻又变成0了;我们不妨打印一下这两个地址看一下:

169af58e3eb1422cbe74156b3364872b.png


发现他们的地址确实是相同的!!!如果你还不懂我们不妨画个图来理解一下,下图是先创建i,在创建数组arr:


216899b444c94bb8b8af12282815837b.png

如果我们先创建数组,在创建i呢?这又是什么情况,这种就不会造成循环,只有越界访问,如下图:



270b621d886c4848b3172dad7b4aaebe.png


以上就是strcpy和strncpy库函数的使用和strcpy函数的模拟实现,希望对你们有所帮助,有错误欢迎指出来,让我进步!!!


18ecb396880243b88c23435d22623a81.jpg

相关文章
|
7月前
strlen,strcpy,stract,strcmp,strstr函数的模拟实现
strlen,strcpy,stract,strcmp,strstr函数的模拟实现
66 3
|
7月前
|
C语言
字符串函数`strlen`、`strcpy`、`strcmp`、`strstr`、`strcat`的使用以及模拟实现
字符串函数`strlen`、`strcpy`、`strcmp`、`strstr`、`strcat`的使用以及模拟实现
135 1
|
2月前
|
存储
strcpy、sprintf 与 memcpy 的区别
在 C 语言中,`strcpy`、`sprintf` 和 `memcpy` 是三个用于处理内存和字符串的函数,它们有不同的用途和特点
|
2月前
解析与模拟常用字符串函数strcpy,strcat,strcmp,strstr(一)
解析与模拟常用字符串函数strcpy,strcat,strcmp,strstr(一)
42 0
|
6月前
|
安全 C语言
strcpy
【6月更文挑战第17天】
86 0
|
存储 Cloud Native Linux
C++ strcpy、sprintf与memcpy的区别
C++ strcpy、sprintf与memcpy的区别
|
7月前
strcat与strncat函数使用与模拟实现
strcat与strncat函数使用与模拟实现
45 0
strcpy与strncpy的模拟与实现
strcpy与strncpy的模拟与实现
53 0
|
C语言
自己实现strcpy和strlen函数
自己实现strcpy和strlen函数
97 0
C实现字符操作函数,strcpy, strcat, strcmp, memcpy
C实现字符操作函数,strcpy, strcat, strcmp, memcpy
57 0