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

相关推荐
C^h7 小时前
c++ string
开发语言·c++
听风说ml7 小时前
socket编程 【C语言】
c语言·udp·tcp·socket编程
raindayinrain7 小时前
c++高性能--原子操作,无锁编程,操作顺序
开发语言·c++·性能优化
学逆向的7 小时前
C++ 合并命名空间
开发语言·c++·网络安全
Zhao-Jichao7 小时前
VS2026 打包 C++ 程序生成 EXE,借助 Installer Project 扩展工具
开发语言·c++
学逆向的8 小时前
C 局部静态变量
c语言·开发语言·网络安全
大都督会赢的8 小时前
C++第一节课
开发语言·c++
“AI国潮设计-小江”8 小时前
【AIGC实战】Python+Stable Diffusion打造“英歌舞财神”IP,解锁“马到成功”等爆款情绪营销文案设计
开发语言·人工智能·python·prompt·aigc
小王C语言9 小时前
Qt常用控件:容器类控件,标题分组框、标签页(浏览器标签)
开发语言·qt
我是唐青枫9 小时前
Kotlin Delegation 委托详解
开发语言·kotlin