当前位置:网站首页>自定义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
边栏推荐
- Server log analysis tool (identify, extract, merge, and count exception information)
- How much do you know about the process of the interview
- 04 Lua operator
- RTKLIB 2.4.3源码笔记
- 关于 background-image 渐变gradient()那些事!
- Paging SQL
- DanceNN:字节自研千亿级规模文件元数据存储系统概述
- RAID磁盘阵列与RAID5的创建
- TypeError: set_ figure_ params() got an unexpected keyword argument ‘figsize‘
- 杂文 谈谈古典的《拆掉思维里的墙》
猜你喜欢
SQL database
ACL 2022 | dialogved: a pre trained implicit variable encoding decoding model for dialogue reply generation
ACL 2022 | DialogVED:用于对话回复生成的预训练隐变量编码-解码模型
Detailed explanation of file operation (2)
Query the data from 2013 to 2021, and only query the data from 2020. The solution to this problem is carried out
VLAN advanced technology, VLAN aggregation, super VLAN, sub VLAN
如何建立 TikTok用户信任并拉动粉丝增长
RAID磁盘阵列与RAID5的创建
How much do you know about the process of the interview
TypeError: set_figure_params() got an unexpected keyword argument ‘figsize‘
随机推荐
04 Lua operator
Pycham connects to the remote server and realizes remote debugging
Camtasia2022软件新增功能介绍
Website_ Collection
Set the color change of interlaced lines in cells in the sail software and the font becomes larger and red when the number is greater than 100
websocket
SQL: How to parse Microsoft Transact-SQL Statements in C# and to match the column aliases of a view
MySQL master-slave synchronization pit avoidance version tutorial
如何建立 TikTok用户信任并拉动粉丝增长
Nacos detailed explanation, something
Detailed explanation of UWA pipeline function | visual configuration automatic test
BUG_ me
Feign report 400 processing
vscode如何比较两个文件的异同
详解牛客----手套
Introduction to new functions of camtasia2022 software
博士申请 | 厦门大学信息学院郭诗辉老师团队招收全奖博士/博后/实习生
◰GL-阴影贴图核心步骤
_ Mold_ Board_
Easyexcel reads the geographical location data in the excel table and sorts them according to Chinese pinyin