51.【C语言】字符函数和字符串函数(strcpy函数)

承接50.【C语言】字符函数和字符串函数(上) 点我跳转

5.strcpy函数

*简单使用

cplusplus的介绍 点我跳转

strcpy:string copy

翻译:

复制字符串

复制由source指向的C字符串到由destionation指向的数组中,包括\0(终止0字符)(在\0那里停止复制)

为了防止溢出,由destionation指向的数组的空间大小必须足够大,以至于能包含作为source的C字符串(含\0),而且不应该覆盖source的内存

参数

destination:指向将要复制内容的destination数组的指针

source:要被复制的C字符串

返回值

destination已经被返回(目标空间的起始地址)

cpp 复制代码
char * strcpy ( char * destination, const char * source );

解释:strcpy(目标,源头);//目标和源头都是char*类型

strcpy(目标,源头);类似汇编的movsb和movsw

汇编中通常以rep和movsb或rep和movsw结合的方式来批量转移字符

movsb(move string byte)

movsw(move string word)

这两个指令都是从DS:SI地址处的数据传送到ES:DI地址处的数据

8086汇编代码示例

(用DOSBox的masm编译)

TypeScript 复制代码
assume cs:code

;定义源头数据段,以byte形式填写,source为数据段的标号
source segment
db 'H','e','l','l','o',' ','W','o','r','l','d','!' 
source ends

;为目标数据段留空间,以byte形式填写,destination为数据段的标号
destination segment
destination: db 0,0,0,0,0,0,0,0,0,0,0,0,0
destination ends

code segment
start:
mov ax,source
mov ds,ax ;ds为source段的段地址

mov ax,destionation
mov es,ax ;es为destination段的段地址

cld  ;设置正方向传输

xor si,si ;si=0
xor di,di ;di=0

mov cx,12 ;设置循环次数为12(Hello World刚好12个字符)

rep movsb ;重复12次传送 每执行一次该指令,si和di自动+1,cx自动-1
code ends
end

注意:上面的**;** 为注释符号

C代码示例

cpp 复制代码
#define   _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>string头文件包含strcpy
int main()
{
	char arr1[] = { "Hello World!"};
	char arr2[20] = { 0 };
	strcpy(arr2, arr1);//注意\0也复制
	printf("%s", arr2);
	return 0;
}

由于arr1和arr2代表数组首元素的地址,因此可以使用strcpy

注意: 1.arr2要预留足够的空间!

2.注意字符串结束标志\0也复制,而且是复制结束的标志!!!在使用的过程中防止越界访问!

3.目标空间必须可以修改(如常量字符串不可修改)

*模拟实现

设计一个函数sim_strcpy

destination简写为dest source简写为src

cpp 复制代码
#define   _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void sim_strcpy(char* dest, char* src)
{
	while (*src != '\0')
	{
		*dest = *src;//解引用,字符复制
		dest++;//指针移动
		src++;//指针移动
	}//字符串结尾的\0没有复制,因此要另加一行
	*dest = *src;
}
int main()
{
	char arr1[] = { "Hello World!"};
	char arr2[20] = { 0 };
	//像strcpy一样设置两个参数
	sim_strcpy(arr2, arr1);
	printf("%s", arr2);
	return 0;
}

*优化

01.简化代码1

cpp 复制代码
*dest = *src;
dest++;
src++;

可以直接写为

cpp 复制代码
*dest++ = *src++;

因此为

cpp 复制代码
while (*src != '\0')
	{
	  *dest++ = *src++;
	}//字符串结尾的\0没有复制,因此要另加一行
	*dest = *src;

可以看到改变前后的汇编指令没有差别,除了最后三行

02.简化代码2

直接写为

cpp 复制代码
while (*dest++ = *src++)//先复制,再判断
	{
	  
	}

先复制一个字符,如果表达式的结果为真,即复制的该字符不为\0,则继续循环,否则结束循环

03.继续修改代码

发现sim_str函数和strcpy有一处不像的地方4

strcpy的返回类型为char*,而sim_strlen返回类型为void

因此改为

cpp 复制代码
#define   _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
char* sim_strcpy(char* dest, char* src)
{
	char* ret = dest;//存储目标空间的起始地址
	while (*dest++ = *src++)
	{

	}
	return ret;
}
int main()
{
	char arr1[] = { "Hello World!"};
	char arr2[20] = { 0 };
	//像strcpy一样设置两个参数
	char* ret = sim_strcpy(arr2, arr1);
	printf("%s", ret);//从ret地址处开始,向后以%s打印
	return 0;
}

附:string.h包含的函数

相关推荐
古希腊掌管学习的神11 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师12 分钟前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
就爱学编程20 分钟前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法
Oneforlove_twoforjob43 分钟前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
emoji11111144 分钟前
前端对页面数据进行缓存
开发语言·前端·javascript
每天都要学信号1 小时前
Python(第一天)
开发语言·python
TENET信条1 小时前
day53 第十一章:图论part04
开发语言·c#·图论
北国无红豆1 小时前
【CAN总线】STM32的CAN外设
c语言·stm32·嵌入式硬件
生信圆桌1 小时前
【生信圆桌x教程系列】如何安装 seurat V5版本R包,最详细安装手册
开发语言·r语言
IT猿手1 小时前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解TP1-TP10及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·深度学习·算法·机器学习·matlab·多目标算法