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包含的函数

相关推荐
o独酌o6 分钟前
递归的‘浅’理解
java·开发语言
Book_熬夜!9 分钟前
Python基础(六)——PyEcharts数据可视化初级版
开发语言·python·信息可视化·echarts·数据可视化
轩轶子36 分钟前
【C-项目】网盘(一期,线程池版)
服务器·c语言
m0_6312704036 分钟前
高级c语言(五)
c语言·开发语言
2401_8582861142 分钟前
53.【C语言】 字符函数和字符串函数(strcmp函数)
c语言·开发语言
程序猿练习生1 小时前
C++速通LeetCode中等第5题-无重复字符的最长字串
开发语言·c++·leetcode
2401_858120261 小时前
MATLAB中的无线通信系统部署和优化工具有哪些
开发语言·matlab
MATLAB滤波1 小时前
【PSINS】基于PSINS工具箱的EKF+UKF对比程序|三维定位|组合导航|MATLAB
开发语言·matlab
2401_858120531 小时前
MATLAB在嵌入式系统设计中的最佳实践
开发语言·matlab
蓝裕安1 小时前
伪工厂模式制造敌人
开发语言·unity·游戏引擎