C语言--模拟实现库函数strcpy

news2024/11/18 2:34:01

目录

  • 前言
  • strcpy实现的基本原理
  • 函数的模拟实现
    • 代码优化
      • assert--断言
      • const关键字
  • strcpy的返回值
  • 结语

前言

本章内容我们将通过相关函数来实现库函数中的strcpy。

strcpy实现的基本原理

C语言 strcpy()函数用于对字符串进行复制(拷贝)。需要的头文件为 <string.h>。原理如下

char* strcpy(char* strDestination, const char* strSource);

其中的strSource为源字符串,strDestination为目的字符串,strcpy的作用就是将 strSource 指向的字符串复制到 strDestination。

我们举个例子

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

打印结果如图1
图1
我们知道字符串arr2实际上是"hello\0",那么我们在打印字符串的时候有没有打印这个\0呢,我们用监视的方法来看一下,如图2
图2
我们发现实际上\0也是被拷贝过来了的。

函数的模拟实现

我们来写一个函数my_strcpy实现字符串的拷贝,框架如下

void my_strcpy(char* dest, char* src)
{

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

图3

当’\0’也被拷贝过去时函数停止运行,我们可以用一个循环来实现代码

void my_strcpy(char* dest, char* src)
{
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}//当src解引用为'\0'时跳出循环,但'\0'还并没有被复制过去
	*dest = *src;//将最后的'\0'也复制过去
}
int main()
{
	char arr1[20] = "xxxxxxxxxxxxxxx";
	char arr2[] = "hello";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

代码优化

上述函数只是我们按照基本思路一步步写出来的,肯定不是最优解,看下面这段代码

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

这段代码才是大师级别的书写格式,它将我们上述的个步骤融为一体,下面我们来分析这段代码。
首先我们将解引用的src的值赋给dest,然后后置++,各自都跳到下一个位置再进行赋值,当最后一次src解引用为’\0’并赋值给dest时,由于’\0’的ascll码值为0,当0被赋值给dest,判断结果也为0,0为假,就会跳出循环,这样既把\0复制了过去,还借此跳出了循环,可谓是一举两得。

assert–断言

假设arr1或arr2为空指针会发生什么呢?显然,空指针是不能解引用的,程序会报错。可是这种情况也是难以避免的,为了避免程序崩溃,我们在函数开头添加一个assert(断言),通过一个判断来选择继续执行或中止代码。

void my_strcpy(char* dest, char* src)
{
	assert(src != NULL);//若为真则继续执行,若为假则终止代码
	while (*dest++=*src++)
	{
		;
	}
}
int main()
{
	char arr1[20] = "xxxxxxxxxxxxxxx";
	char arr2[] = "hello";
	my_strcpy(arr1,NULL);
	printf("%s\n", arr1);
	return 0;
}

我们假定arr2为空指针,代码运行结果就会如下
图4
这样,我们既可以有效防止程序崩溃,还可以很清晰的在代码中锁定出问题的地方(比如途中出问题的地方就为源.c line27)。

const关键字

如果我们在函数书写中把拷贝对象和被拷贝对象写反了,会发生什么呢?

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

代码运行结果如图5
图5
我们会发现程序崩溃了,原因在于arr2字符串长度放不下arr1。但如果我们加入const关键字修饰就能很好的规避这个问题。

const关键字的作用在于修饰变量,这个变量就被称为常变量,它具备了常量的属性,但本质上还是一个变量。
但我们来看一段代码

int main()
{
    const int num = 10;
	int* p = &num;
	*p = 20;

	printf("%d\n",num);
}

运行结果如图6
图6
我们发现,被const修饰的变量num还是被修改了,我么要想保持num不变,就需要修饰指针变量

int main()
{
    int num = 10;
	const int* p = &num;
	*p = 20;

	printf("%d\n",num);
}

这样* p=20这段代码将无法实行。这是因为const如果放在* 左边,修饰的是*p,表示的是指针指向的内容,是不能通过指针来改变的,但是指针变量本身( p )是可以修改的,如果放在 *右边,修饰的就是p,和放在左边完全相反,指针变量本身将无法被修改,但指针指向的内容却可以被修改,num还是会被修改为20

strcpy的返回值

strcpy这个库函数的执行原理实际上是会返回目标空间的起始地址

char* my_strcpy(char* dest, const char* src)
{
	assert(src != NULL);
	assert(dest != NULL);
	char* ret = dest;
	while (*dest++=*src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[20] = "xxxxxxxxxxxxxxx";
	char arr2[] = "hello";
	//目标空间的起始地址 源空间的起始地址
	my_strcpy(arr1,arr2);
	printf("%s\n", my_strcpy(arr1,arr2);//链式访问
	return 0;
}

结语

以上就是标准的库函数strcpy的模拟实现流程,如有出入,欢迎指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195331.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IPtables进行端口复用

目录第一种方式&#xff1a;ICMP做遥控开关1、创建端口复用链2、创建端口复用规则&#xff0c;将流量转发至22端口3、开启开关4、关闭开关5、lets do it第二种方式&#xff1a;利用tcp数据包的关键字做遥控开关1、端口复用链2、端口复用规则(与上面一致)3、开启开关4、关闭开关…

手机上怎么制作动图?两招教你手机在线制作gif动画

想要在手机上制作gif动态图片&#xff0c;还不想下载软件的时候要怎么办呢&#xff1f;很简单&#xff0c;下面给大家分享两招在线gif制作&#xff08;https://www.gif.cn/&#xff09;的工具&#xff0c;不需要下载任何软件。小白也能轻松上手&#xff0c;支持原画质导出&…

STM32 (十五)ESP8266WIFI

简介1 ESP8266wifi 模块低功耗串口WiFi模块ESP8266内置一个Tensilica&#xff08;泰思立达&#xff09; Xtensa架构的32位处理器L106&#xff0c;具有5级流水线(ARM CortexM3是3级流水线)&#xff0c;最大时钟速度为160MHz&#xff0c;可以使用高达16MB的外部SPI Flash。 该模块…

Kotlin Navigation开发

前言 其实小编之前一直都是用的Java来开发Android&#xff0c;但是工作需求&#xff0c;开始了Kotlin的编程&#xff0c;接触到了JetPack&#xff0c;发现其中的Navigation特别有意思&#xff0c;今天来给大家分享一下&#xff0c;我们做一个四个页面吧&#xff0c;从APP的 欢…

2023年PMP考试如何备考?

下面我给各位正在学习备考或者正在犹豫是否报名的朋友分享下我的想法和学习经验&#xff0c;希望对各位朋友有帮助。 一&#xff0c; 关于读PMBOK 在整个学习和备考期间我总共读了五遍PMBOK&#xff0c;第一遍是粗略的读&#xff0c;在读的时候一定要有耐心&#xff0c;因为在…

电商系统的高质量容量保障是怎样“炼成”的?

一分钟精华速览 容量保障的目标是保证服务在大量用户访问时&#xff0c;依然可以正常为用户提供服务。比如&#xff0c;在“双11”购物节的超高访问量下&#xff0c;各电商系统依然能够稳定地运行&#xff0c;可以说容量保障是所有技术人都应当具备的技能。 知名技术博主老张…

【0-1背包变式题】何以包邮(来自Acwing寒假每日一题)

⭐️前面的话⭐️ 本篇文章介绍来自一道0-1背包的变式原题&#xff0c;展示语言java/C。 &#x1f4d2;博客主页&#xff1a;未见花闻的博客主页 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4cc;本文由未见花闻原创&#xff0c;…

振弦采集模块监测传感器频率值不稳定

振弦采集模块监测传感器频率值不稳定 基本概念 振弦传感器&#xff1a;&#xff08;vibrating wire sensor&#xff09;是以拉紧的金属钢弦作为敏感元件的谐振式传感器。当弦的长度确定之后&#xff0c;其固有振动频率的变化量即可表征钢弦所受拉力的大小。根据这一特性原理&a…

2023华数杯B题社会稳定预警研究的材料支撑以及解题思路【全网独家社会稳定预警研究材料支撑】

B题社会稳定预警研究 材料支撑&#xff1a;&#xff08;动态链接&#xff0c;后期会一直不断新增支撑论文进去&#xff09; 社会稳定预警研究材料支撑合集下载 部分截图如下&#xff1a;&#xff08;还会不断更新&#xff09; 题目问题B&#xff1a;社会稳定预警研究 人类和…

【C语言】文件相关函数详解

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;别人可以拷贝我的模式&#xff0c;但不能拷贝我不断往前的激情 &#x1f6f8;C语言专栏&#xff1a;https://blog.csdn.net/vhhhbb/category_12174730.html 小苏希望大家能从这篇文章中收获到许…

C++类基础(四)

访问限定符与友元 ● 使用 public/private/protected 限定类成员的访问权限 //main.cpp struct Str { //结构体默认的访问权限&#xff0c;可以省略 //public:int x 0; private:int y 0; };int main() {Str m_str;//OK: 在同一个翻译单元内&#xff0c;结构体struct Str { .…

单车价值超整车售价?智能汽车「新赛道」扎堆供应商

汽车网络安全赛道正在进入新周期。 1月初&#xff0c;HL Mando与全球汽车网络安全方案提供商Argus Cyber Security达成协议&#xff0c;扩大网络安全技术合作。前者将Argus CAN入侵检测系统&#xff08;IDS&#xff09;解决方案应用于刹车和转向等电气化系统产品。 目前&#x…

希尔排序基本思想示例及代码

希尔排序是插入排序的一种&#xff0c;直接插入排序相关内容可见&#xff1a; https://blog.csdn.net/weixin_43978384/article/details/128836898?spm1001.2014.3001.5502 1、算法思想 希尔排序又称“缩小增量”的排序&#xff0c;属于插入排序的一种。希尔排序的基本思想是…

Springboot+ssm企业员工考勤管理系统

毕业的进度&#xff1a; 第一阶段 系统概要设计&#xff0c;设计系统架构&#xff0c;数据库模型 第二阶段 完成模块的开发与测试 第三阶段 实现主要模块 本公司员工管理系统的设计与实现以Springboot作为框架&#xff0c;B/S模式以及MySql作为后台运行的数据库。…

2023年深圳积分入户考这个软考高级证书错不了!加分真高!

信息系统项目管理师是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目之一&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资…

最完整的文档成像工具包:GdPicture.NET Crack

GdPicture.NET企业级智能 PDF 和文档处理 SDK&#xff0c;使用最先进的人工智能、机器学习和模糊逻辑算法的高度复杂的 API 集。经过超过 15 年专注于创新的持续研究&#xff0c;GdPicture.NET 已成为市场上最全面的PDF、OCR、条形码、文档图像和格式的 SDK 。 最佳文档影像 SD…

设计模式之装饰器模式,以C++为例。

昨天更新了适配器&#xff0c;今天来盘一盘装饰器模式。装饰器模式以一种动态的方式给对象添加额外的职责&#xff0c;好似“装饰”在对象身上一样&#xff0c;通常通过继承和委托来实现。 目录 一、装饰器模式介绍 二、游戏人物如何使用装饰器模式 三、进阶写法&#xff08;…

VScode ssh远程登陆到服务器阅读代码

1、背景介绍在工作中经常使用ssh远程访问服务阅读代码&#xff0c;但是通过ssh远程访问后没有图形界面&#xff0c;阅读代码非常不方便&#xff0c;本文向大家介绍使用VScode通过ssh远程登陆到服务器&#xff0c;本地可视化阅读查看服务器的代码文件。2、安装VS CodeVisual Stu…

Nginx优化

一.设置Nginx运行进程个数 1.查看cpu个数 grep processor /proc/cpuinfo 使用top 按1,也可以查看cpu的核心数 2.设置Nginx进程数 我的cpu数量是4,修改为4 vim /usr/local/nginx/conf/nginx.conf 二.Nginx运行CPU亲和力 vim /usr/local/nginx/conf/nginx.conf 4核4线程配置 注…

叠氮试剂1379690-01-3,3-Azido-D-alanine HCl,3-叠氮-D-丙氨酸HCl

产品规格&#xff1a;3-叠氮-D-丙氨酸HCl&#xff0c;3-Azido-D-alanine HCl1.CAS号&#xff1a;1379690-01-32.分子式&#xff1a;C3H7ClN4O23.分子量&#xff1a;166.566284.包装规格&#xff1a;1g&#xff0c;5g&#xff0c;10g&#xff0c;包装灵活&#xff0c;有100mg包装…