当前位置:网站首页>自定义my_strcpy与库strcpy【模拟实现字符串相关函数】
自定义my_strcpy与库strcpy【模拟实现字符串相关函数】
2022-04-23 16:54:00 【马桶上看算法】
学习很苦,结果很酷
️ 温馨提示:
各位童鞋们在内卷的的道路上千万要注意身体,不要一整天的坐在电脑前,多运动运动。
目录
一、用库函数strcpy实现字符串拷贝
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxx";
char arr2[20] = "hello";
strcpy(arr1, arr2);//arr1目标空间起始地址,arr2源空间起始地址
printf("%s\n", arr1);
return 0;
}
当前代码打印hello就结束了,因为strcpy函数不仅把hello拷贝过去了,连同后面的\0也一同拷贝过去了,字符串结束标志是\0,也就只会打印出hello了。
二、自定义my_strcpy实现字符串拷贝
数组名是首元素的地址,也就是char的地址
用my_strcpy将src指向的内容拷贝到dest所指向的空间
当把h拷贝过去后,要拷贝其他的内容就要使dest和src指向下一个内容
#include<stdio.h>
#include<string.h>
void my_strcpy(char* dest, char* src)//dest表示目的地,src表示源头
{
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxx";
char arr2[20] = "hello";
my_strcpy(arr1, arr2);//arr1目标空间起始地址,arr2源空间起始地址
printf("%s\n", arr1);
return 0;
}
对于指针有不理解的,可以去看我往期的文章
三、my_strcpy拷贝字符串优化版
1.第一种
*dest++ = *src++是hello的拷贝
*dest = *src是\0的拷贝
️ 2.第二种
先将h赋给*dest,h的ASCII值不等于0。后面分别将e、l、l、o赋给*dest,它们的ASCII值均不等于0,但将\0赋给*dest的时候,\0的ASCII值是0,表达式为假,所以循环结束了。
四、my_strcpy拷贝字符串深度优化
1.使用assert()断言
如果arr1或者arr2是空指针(NULL),就意味着dest或者src哪里都没有指向,这时如果再解引用就会出问题。
解决办法:assert()//断言
我们的程序应该有能力检查arr1和arr2是不是一个空指针,如果是就提示,如果不是就运行。assert()和if()非常类似,只不过assert()圆括号里的表达式为真,就什么事都不发生,为假,就提示错误。
例如:
assert(src != NULL)
另外assert的使用要引头文件
#include<assert.h>
️
注意:assert()为真就什么都不发生,而为假就提示错误,这和if语句刚好相反,使用的时候注意别搞混淆了。
#include<stdio.h>
#include<string.h>
#include<assert.h>
void my_strcpy(char* dest, char* src)//dest表示目的地,src表示源头
{
assert(src != NULL);//断言
while (*dest++ = *src++)
{
}
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxx";
char arr2[20] = "hello";
my_strcpy(arr1, NULL);//arr1目标空间起始地址,arr2源空间起始地址
printf("%s\n", arr1);
return 0;
}
arr1和arr2都有可能是NULL,所以要对两个都进行断言
代码如下:
#include<stdio.h>
#include<string.h>
#include<assert.h>
void my_strcpy(char* dest, char* src)//dest表示目的地,src表示源头
{
assert(dest != NULL);//断言dest
assert(src != NULL);//断言src
while (*dest++ = *src++)
{
}
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxx";
char arr2[20] = "hello";
my_strcpy(arr1, arr2);//arr1目标空间起始地址,arr2源空间起始地址
printf("%s\n", arr1);
return 0;
}
️2.添加const
如果将源空间起始地址和目标空间起始地址弄反了,写成了*src++ = *dest++,字符串拷贝考反了,将arr1中的字符串(一堆x)拷贝到arr2中去,程序就会崩溃,因为arr2放不下arr1的内容
当我们将源空间起始地址和目标空间起始地址弄反了,怎么能够及时的发现呢?
解决办法:const
将源空间地址前加上一个const
例如:
void my_strcpy(char* dest, const char* src)
当我们加上const之后,再去编译代码,将*dest拷贝给*src,程序就会报错;而原来就算是写反了,程序也可以跑起来,加上const之后程序连跑都跑不起来,也就不会出现运行上的错误了。
那么加上一个从const就是一个很好的保护
️
注意:如果*dest和*src没有写反,即使是加了const程序也不会报错
代码如下:
#include<stdio.h>
#include<string.h>
#include<assert.h>
void my_strcpy(char* dest, const char* src)//dest表示目的地,src表示源头
{
assert(dest != NULL);
assert(src != NULL);//断言
while (*dest++ = *src++)
{
}
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxx";
char arr2[] = "hello";
my_strcpy(arr1, arr2);//arr1目标空间起始地址,arr2源空间起始地址
printf("%s\n", arr1);
return 0;
}
️ 3.const修饰指针
现在要求num的值不能被改变,要在num左边加上一个const,也就是这样写:
const int num = 10;
const的作用是修饰变量,这个变量被称为常变量,具有常属性,不能被修改,但本质上还是一个变量。
当我们运行代码会发现,即使是加上了const,num的值还是被改变了。
加入const的初衷就是不能改变num的值,但现在还是改变了。虽然num被const修饰,num的值不能改变,但num又将自己的地址交给了p。通过对p解引用还是将num的值给改变了。比如我们要进入教室,正常情况下只能从门进去,但是现在门被锁住了,我们还可以从窗户进去。
我们加入const的目的非常明确,那就是使num的值不能被改变。这里通过访问地址的方式还是可以将num的值改变,看似挺巧妙的,但这不符合我们的要求。那要怎么做才能把窗户也锁上呢?
解决办法:将p的左边也加入一个const
也就是这样写:
const int* p = #
运行代码就会发现,程序会报错。在这里也就相当于是把窗户也锁住了。
代码如下:
#include<stdio.h>
int main()
{
const int num = 10;
const int* p = #
//const修饰指针的时候
//const如果放在*的左边,修饰的是*p,表示指针指向的内容,是不能通过指针改变的
*p = 20;
printf("%d\n", num);
return 0;
}
️
注意:虽然const修饰的是*p,但是对我的指针变量p没有影响
#include<stdio.h>
int main()
{
const int num = 10;
const int* p = #
//const修饰指针的时候
//const如果放在*的左边,修饰的是*p,表示指针指向的内容,是不能通过指针改变的
//*p = 20;
//但是指针变量本身是可以修改的
int n = 100;
p = &n;//修改了p变量本身
printf("%d\n", num);
return 0;
}
当前代码运行结果为: 10
️ 4.凉皮男孩上线
以上的情况是const放在*左边,下面来介绍const放在*右边。
比如说现在有一个女孩和男孩1,他们是男女朋友关系。男孩有十块钱,女孩想吃凉皮了,让男孩给她买凉皮,而一碗凉皮要十块钱,这个时候发生的动作是*p = 0,就是相当于男孩把十块钱花掉了。
其实这个男孩很抠,他在想我只有十块钱,请你吃了,我就没钱了,那我才不要请你吃。于是他想了一个办法,就是在*的左边加上一个const。修饰*p,这个时候*p = 0这个动作就不能完成了。
女孩生气了,十块钱你都舍不得,我看男孩2也挺帅的,分手吧!我去作男孩2的女朋友了。这个时候发生的动作是p = &n。
这个时候男孩1慌了,你要跟我分手,那那那那那不行,于是男孩叕想到了一个办法,那就是在*的右边加上const。
有一天,男孩想到了一个坏主意。那就是将*的两边都加上const
版权声明
本文为[马桶上看算法]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_63033419/article/details/124334814
边栏推荐
- 杂文 谈谈古典的《拆掉思维里的墙》
- New project of OMNeT learning
- Pycham connects to the remote server and realizes remote debugging
- Nodejs reads the local JSON file through require. Unexpected token / in JSON at position appears
- Bytevcharts visual chart library, I have everything you want
- Talk about browser cache control
- Get the column name list of the table quickly in Oracle
- About background image gradient()!
- DanceNN:字节自研千亿级规模文件元数据存储系统概述
- 英语 | Day15、16 x 句句真研每日一句(从句断开、修饰)
猜你喜欢
Idea of batch manufacturing test data, with source code
Installation and management procedures
The font of the soft cell changes color
Pycham connects to the remote server and realizes remote debugging
Path environment variable
NVIDIA显卡驱动报错
File upload and download of robot framework
Mock test using postman
loggie 源码分析 source file 模块主干分析
[pimf] openharmony paper Club - what is the experience of wandering in ACM survey
随机推荐
DanceNN:字节自研千亿级规模文件元数据存储系统概述
_ Mold_ Board_
信息摘要、数字签名、数字证书、对称加密与非对称加密详解
聊一聊浏览器缓存控制
PostgreSQL列存与行存
Xinwangda: HEV and Bev super fast charging fist products are shipped on a large scale
Talk about browser cache control
05 Lua control structure
Loading order of logback configuration file
Detailed explanation of information abstract, digital signature, digital certificate, symmetric encryption and asymmetric encryption
SQL database
关于局域网如何组建介绍
安装及管理程序
STM32__03—初识定时器
Kunteng full duplex digital wireless transceiver chip kt1605 / kt1606 / kt1607 / kt1608 is suitable for interphone scheme
Cartoon: what are IAAs, PAAS, SaaS?
VLAN高级技术,VLAN聚合,超级Super VLAN ,Sub VLAN
英语 | Day15、16 x 句句真研每日一句(从句断开、修饰)
PyMySQL
Do you really understand the principle of code scanning login?