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

相关推荐
仟濹19 分钟前
【二分搜索 C/C++】洛谷 P1873 EKO / 砍树
c语言·c++·算法
服务端相声演员1 小时前
Oracle JDK、Open JDK zulu下载地址
java·开发语言
YH_DevJourney1 小时前
Linux-C/C++《C/8、系统信息与系统资源》
linux·c语言·c++
19岁开始学习1 小时前
Go学习-入门
开发语言·学习·golang
青铜念诗1 小时前
python脚本文件设置进程优先级(在.py文件中实现)
开发语言·python
一念春风2 小时前
C# 背景 透明 抗锯齿 (效果完美)
开发语言·c#
Igallta_8136222 小时前
【小游戏】C++控制台版本俄罗斯轮盘赌
c语言·开发语言·c++·windows·游戏·游戏程序
Dyan_csdn2 小时前
【Python项目】文本相似度计算系统
开发语言·python
pianmian12 小时前
python绘图之回归拟合图
开发语言·python·回归
大G哥2 小时前
用DeepSeek来帮助学习three.js加载3D太极模形
开发语言·前端·javascript·学习·ecmascript