字符串函数内存函数(从零到一)【C语言】

长度不受限制的字符串函数:strcpy,strcat,strcmp

长度受限制的字符串函数:strncpy,strncat,strncmp

 strlen

 strlen函数是库函数中我们最常使用的函数,它可以求出字符串的长度(不包含‘\0’)

使用方法

通过前面对strlen函数的模拟实现我们知道strlen计算长度时,是遇到'\0'才停止的,因此如果一个字符串中没有'\0',程序就会输出一个随机值,如下面代码:

 因此我们在使用该函数时,必须避免这种情况。

注意:库函数中的strlen函数的类型是size_t(无符号整形)

模拟实现该函数的功能

这个函数我们实现的次数已经够多了,所以不再过多赘述,在此提供几种方法:

1.指针- 指针          2.计数器              3.递归

strcpy 

 strcpy函数用于将源字符串复制到目标字符串中,包括字符串的结束符'\0'。

使用方法

char* strcpy(char* destination, const char* source);

在使用strcpy函数时也要避免缺少'\0'的情况,此外,目标字符串必须具有足够的空间来存储源字符串的内容。

 模拟实现该函数的功能

#include<stdio.h>
#include<string.h>
void get_strcpy(char* des,const char* sou)//此处加const的原因是防止原字符串的内容被修改
{
	assert(sou != NULL);
	while (*des++ = *sou++)
	{
		;	
	}	
}
int main()
{
	char arr1[10] = " xxxxxxx ";
	char arr2[10] = "bit";
	get_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

strcat 

strcat是一个字符串追加函数,它可以把一个字符串追加给另一个字符串后面。

char* strcat(char* destination, const char* source);

使用方法

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

 

 模拟实现该函数的功能

#include<stdio.h>
char* my_strcat(char* dest, char* sou)
{
	char* ori = dest;
	//找到源字符串中的\0
	while (*dest)
	{
		dest++;
	}
	//开始追加
	while (*dest++ = *sou++)
	{
		;
	}
	return ori;
}
int main()
{
	char arr1[30] = "hello ";
	char arr2[] = "world";
	printf("%s\n",my_strcat(arr1, arr2));
	return 0;
}

注意事项

字符串不能自己给自己追加,通过模拟实现该函数我们发现,追加的标志是'\0',在追加开始时,'\0'就被自己的第一个元素覆盖,原先在准备追加最后一位'\0'的位置已经变成了一个正常的元素,所以循环将一直继续,不会终止。

strstr

该函数的功能是在一个字符串中查找另一个函数,如果查找到,则返回起始位置的地址,如果找不到,则返回一个空指针。

使用方法

char *strstr( const char *string, const char *strCharSet );

第一个参数是源字符串,第二个参数是要查找的字符串。 

模拟实现该函数的功能

#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* tmp = str1;
	if (*str2 == '\0')
	{
		return (char*)str1;
	}
	while (*tmp)
	{
		s1 = tmp;
		s2 = str2;
		while (*s1 && *s2 && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)tmp;
		}
		tmp++;
	}
	return NULL;
}
int main()
{
	char arr1[30] = "aabbccd";
	char arr2[] = "bcc";
	char* pa = my_strstr(arr1, arr2);
	printf("%s\n", pa);
	return 0;
}

 memcpy

memcpy函数是一个内存操作函数,用于在内存中进行数据的复制。它将指定长度的数据从源地址复制到目标地址,不考虑源地址和目标地址是否重叠。当源地址和目标地址有重叠时,使用memcpy函数可能导致不可预测的结果。

该函数出现的原因:字符串的拷贝可以使用strcpy函数来进行,但是通过模拟实现strcpy的功能时,我们可以发现,strcpy拷贝结束的标志是‘\0’,但是如果拷贝的是一个整形数组,该函数就不再适用了,因此出现了这种更为通用的函数memcpy(内存拷贝函数)

该函数基本的使用方法:void *memcpy( void *dest, const void *src, size_t count );

使用方法

在msdn上可以查询出该函数的基本使用方式,前两个参数都是void类型的指针,意味着我们可以传入任意类型的指针参数,后面的size_t是无符号的整形,单位是字节,意味着操作者可以传入自己想要拷贝的字节。

模拟实现该函数的功能

当你对一个指针进行加1操作时,实际上会将指针的值增加一个与指针所指向的数据类型大小相等的偏移量。这个偏移量是以字节为单位计算的。

举个例子,如果一个指针指向整型数据(int),那么对该指针进行加1操作后,指针将向后移动4个字节(因为int类型通常占用4个字节)。类似地,如果指针指向字符型数据(char),那么对该指针进行加1操作后,指针将向后移动1个字节。

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* sou, size_t k)//k的单位是字节
{
    assert(dest && sou);
	void* orignal = dest;
	while (k--)
	{
		*(char*)dest = *(char*)sou;
		dest = (char*)dest + 1;
		sou = (char*)sou + 1;
	}
	return orignal;
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	my_memcpy(arr2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

 标准功能的memcpy函数其实不能实现内存重叠的拷贝,比如说对于数组int arr[10] = {1,2,3,4,5,6,7,8,9,10 };我们如果使用memcpy(arr+2,arr,20),结果应该是1,2,1,2,1,2,7,8,9,10.因为存在内存重叠。但是VS上却能够正常编译,因为VS把这个函数的功能做的比较彻底,算是PLUS版本的memcpy函数,超出了本身固有的功能。对于内存重叠的拷贝我们其实还有一个特定的函数memmove,下面展开介绍。

memmove

 memmove 函数是一个内存操作函数,用于在内存中移动一段数据。它可以处理源地址和目标地址有重叠的情况,保证数据的正确复制。

使用方法

其使用方法与memcpy相似。 

模拟实现该函数的功能 

通过分析,我们发现,为保证字符串拷贝不受内存重叠的影响,当dest的指针小于sou的指针的时候要从前向后拷贝,当dest的指针大于等于sou的指针的时候要从后向前拷贝,当dest的指针大于sou+宽度时,不管是从后向前还是从前到后拷贝都可以。

总结:当dest的指针小于sou的指针的时候从前向后拷贝,dest的指针大于等于sou的指针的时候从后向前拷贝。

#include<stdio.h>
#include<string.h>
char* my_memmove(void* dest, const void* sou, size_t k)
{
	char* original = dest;
	if (dest < sou)
	{
		while (k--)
		{
			*(char*)dest = *(char*)sou;
			dest = (char*)dest + 1;
			sou = (char*)sou + 1;
		}
	}
	else
	{
		while (k--)
		{
			*((char*)dest + k) = *((char*)sou + k);
		}
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr + 2, arr, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

memcmp

memcmp与strcmp的函数设计相似, 比较特定的字节后,如果值相同,返回值为零;如果不同,返回值是一个负数;如果相同,返回一个正数。

int memcmp(const void* ptr1, const void* ptr2, size_t num);

ptr1和ptr2分别是要比较的内存区域的起始地址,num是要比较的字节数。

使用方法

#include <stdio.h>
#include <string.h>

int main()
{
    char str1[] = "Hello";
    char str2[] = "World";

    int result = memcmp(str1, str2, sizeof(str1));

    if (result == 0)
    {
        printf("字符串相等\n");
    } 
    else if (result < 0) 
    {
        printf("str1小于str2\n");
    } 
    else 
    {
        printf("str1大于str2\n");
    }

    return 0;
}

memset

memset是库函数中的一个函数,用于将一段内存块的值设置为指定的值 ,

void *memset(void *ptr, int value, size_t num);

使用方法 

需要注意的是,memset函数只能设置每个字节的值,因此在设置非字符类型的数组时需要小心。另外,memset函数只能设置为整数值,不能设置为其他类型的值。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

考研小白助力宝典(2)

前言 考研&#xff0c;是一场耗时长久的脑力之战&#xff0c;刻苦勤奋的态度和披荆斩棘的精神外&#xff0c;往往取决于谁抓好了信息利剑&#xff01;合理得当利用好信息平台&#xff0c;就已经快人一步战胜了大部分的竞争对手了&#xff01; 目录 着重学习练习 考研相关简介 …

小白向攻略简单易懂,怎么用DomoAI将手机里面的视频转换成丝滑流畅高帧数的动画

Domo AI是一款强大的人工智能工具&#xff0c;支持图像和视频的重新创作。它拥有超过10个多样化的预设模型&#xff0c;使用户能够轻松实现一致且统一的艺术风格。 在图像生成方面&#xff0c;Domo AI能够快速将照片转换成动漫或现实风格&#xff0c;同时还支持将素描或线稿重…

关于“Python”的核心知识点整理大全33

目录 12.8.3 将子弹存储到编组中 alien_invasion.py 注意 12.8.4 开火 game_functions.py 12.8.5 删除已消失的子弹 alien_invasion.py 12.8.6 限制子弹数量 settings.py game_functions.py 12.8.7 创建函数 update_bullets() game_functions.py alien_invasion.py…

redhawk中short引起的ir drop为0的情况

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 问题如图&#xff0c;顶层在做redhawk分析时读了top及block的def&#xff0c;但top def中并没有把block pg pin写到top 的pg net下&#xff0c;导致redhawk认为有short存在&…

获投1050万欧元!德国量子公司Kipu Quantum成功研发特定压缩算法

​&#xff08;图片来源&#xff1a;网络&#xff09; 近日&#xff0c;德国量子软件公司Kipu Quantum宣布成功完成种子轮融资&#xff0c;融资总额达1050万欧元&#xff08;约合8000万人民币&#xff09;。该初创公司目前已开发出运行高性能量子计算机所需的压缩算法。该算法…

迎接新技术挑战,JFrog发布与升级系列黑科技技术产品

作为开发者&#xff0c;我们十分关注软件开发的全生命周期&#xff0c;有一家企业也同样关注软件交付和流式软件&#xff0c;致力创造从开发人员到设备之间畅通无阻的软件交付世界。它便是 JFrog&#xff0c;自2008年成立以来&#xff0c;目前已在全球范围内拥有7200家客户&…

2024年天津理工大学中环信息学院专升本报名考务费网上缴费说明

2024年天津理工大学中环信息学院高职升本考试报名考务费网上缴费说明 通过资格审核的考生&#xff0c;须在2023年12月22日至12月25日每天8:00-17:00完成考务费缴费&#xff0c;网上缴费参照津发改价费【2020】371号文件&#xff0c;左右考试考务费&#xff1a;80元&#xff08…

Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580

Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580 已亲自复现) 漏洞名称 漏洞描述 Apache ShenYu是一个异步的&#xff0c;高性能的&#x…

如何在 FastAPI 中设置定时任务:完全指南

Web 应用程序开发中&#xff0c;及时高效处理常规任务至关重要&#xff0c;包括定时收集数据或管理任务计划。针对强大且性能卓越的 FastAPI 框架&#xff0c;我们可以通过几种策略来管理这些必要的定时任务。 实现 FastAPI 中的定时任务 本指南将探讨在 FastAPI 环境中管理定…

Git初始

一)git的介绍: 1)假设现在有一个文档&#xff0c;你的老板要求你针对于这份文件进行修改&#xff0c;进行完成的修改的版本是版本1&#xff0c;接下来是文档2&#xff0c;修改完文档2以后&#xff0c;接下来老板还不同意&#xff0c;于是又有了文档三&#xff0c;文档四&#x…

Ubuntu 常用命令之 less 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 less命令是一个在Unix和Unix-like系统中用于查看文件内容的命令行工具。与more命令相比&#xff0c;less命令提供了更多的功能和灵活性&#xff0c;例如向前和向后滚动查看文件&#xff0c;搜索文本&#xff0c;查看长行等。 les…

算法和算法分析

一个问题抽象为一个抽象数据类型后&#xff0c;仅是形式上的抽象定义&#xff0c;还没有达到问题解决的目的&#xff0c;要实现这个目标&#xff0c;就要吧抽象的变成具体的&#xff0c;即抽象数据类型再计算机上实现&#xff0c;变为一个能用的具体的数据类型&#xff01; …

Unity | Shader基础知识(第八集:案例<漫反射材质球>)

目录 一、本节介绍 1 上集回顾 2 本节介绍 二、什么是漫反射材质球 三、 漫反射进化史 1 三种算法结果的区别 2 具体算法 2.1 兰伯特逐顶点算法 a.本小节使用的unity自带结构体。 b.兰伯特逐顶点算法公式 c.代码实现——兰伯特逐顶点算法 2.2 代码实现——兰伯特逐…

如何开启In-sensor zoom 功能

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、In-sensor zoom 概述二、如何开启 In-sensor zoom2.1 开启 camxsettings.xml setting2.2 多摄像头&#xff0c;需要添加特殊的逻辑2.3 在 MetaTran…

记录下IAP升级将APP程序修改正常模式下载失败 No Algorithm found for: 08000000H - 08008FFFH

移植发现问题&#xff1a; No Algorithm found for: 08000000H - 08008FFFH 今天在调试程序时&#xff0c;需要把钱同事程序的APP修改成成正常下载就可以用的程序&#xff0c;工程的地址复位也把APP的偏移地址去掉&#xff0c;理论上这样就OK了 偏移地址设置也屏蔽了 STLINK下…

美摄AE模板插件工具,将美摄SDK和AE极致融合

视频内容已经成为企业宣传和品牌建设的重要手段&#xff0c;为了满足企业对于高质量视频制作的需求&#xff0c;美摄科技推出了一款创新性的插件工具——美摄AE模板插件工具。这款工具将美摄SDK能力和Adobe After Effects极致融合&#xff0c;为企业提供了一种快速制作和转化美…

vue 历程记

目录 前言一、源码优化1、vue3.x 采用 monorep 的理念来管理源码2、vue3.x 源码采用 TypeScript 开发 二、性能优化1、减少源码的体积2、数据劫持优化3、编译优化&#xff08;1&#xff09;、编译粒度的优化 三、语法 API 的优化1、优化了编码的逻辑组织2、优化了代码的逻辑复用…

Java学习系列(四)

1.Scanner类 java.util.Scanner 是 Java5 的新特征&#xff0c;我们可以通过 Scanner 类来获取用户的输入。 import java.util.Scanner; public class ScannerDemo {public static void main(String[] args) {Scanner scan new Scanner(System.in);// 从键盘接收数据// next…

css学习笔记2

css学习笔记2 CSS三大特性1.三大特性1.1层叠性1.2继承性1.3优先级 2.颜色的表示2.1表示方式一&#xff1a;颜色名2.2表示方式二&#xff1a;rgb或rgba2.3表示方式三&#xff1a;HEX或HEXA2.4表示方式四&#xff1a;HSL或HSLA CSS三大特性 1.三大特性 1.1层叠性 概念&#xff…

SLAM算法与工程实践——SLAM基本库的安装与使用(6):g2o优化库(1)g2o库的安装

SLAM算法与工程实践系列文章 下面是SLAM算法与工程实践系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 SLAM算法与工程实践系列文章链接 下面是专栏地址&#xff1a; SLAM算法与工程实践系列专栏 文章目录 SLAM算法与工程实践系列文章SLAM算法与工程实践…