字符串函数和内存函数详解(1)

news2024/11/25 10:04:18

🐵本文将通过函数原型、用法、模拟实现等多个方面全面讲解字符串的库函数

1.strlen📚

1.1函数用法📗

strlen函数用来计算字符串的长度,它会从接收到字符的地址开始读取直到遇到'\0',每读取一个非'\0'的字符长度+1,最后返回一个size_t(无符号)类型的数

strlen函数原型:

返回类型为size_t,参数是一个字符指针用来接收字符的地址

1.2具体实现📕

#include<stdio.h>
#include<string.h> //记得加上头文件

int main()
{
	char arr[] = "abcedf";
	size_t len = strlen(arr);
	printf("%zd", len); //结果为6

	return 0;
}

1.3模拟实现📘

这里总结了三种strlen函数模拟实现的方法,分别为:计数器、指针-指针和递归

计数器

size_t my_strlen1(const char* arr) //计数器
{
	size_t count = 0;
	while (*arr++ != '\0')
	{
		count++;
	}
	return count;
}

递归

size_t my_strlen(const char* arr)
{
	if (*arr != '\0')
	{
		return 1 + my_strlen(++arr);
	}
	else
	{
		return 0;
	}
}

每次递归都判断以下arr指针是否指向'\0',如果是则返回0,不是则指向下一个字符进行判断并且长度+1

指针-指针

size_t my_strlen2(const char* arr)
{
	char* p = arr;
	while (*arr != '\0')
	{
		arr++;
	}

	return arr - p;
}

指针-指针用来计算两个指针之间元素的个数,先让p指向字符串的首地址,之后通过while循环使arr指向'\0',最后返回arr - p

2.strcpy📚

2.1函数用法📗

strcpy函数用来拷贝字符串将源数组中的字符串拷贝到目标数组中,但需要注意以下几点:

  • 目标数组可能没有'\0',所以strcpy再拷贝时会将源数组的'\0'也拷贝过去,也就是说源数组中必须有'\0'
  • 目标数组的空间必须足够大,确保其在被拷贝后能存放的下字符串
  • 目标数组必须可变,不能是常量字符串

strcpy函数原型:

返回类型为char*,destination用来接收目标数组的地址,source用来接收源数组的地址

2.2具体实现📕

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

int main()
{
	char arr1[20] = { 0 }; //目标数组空间确保能存放源数组
	char arr2[] = "abcdef";
	strcpy(arr1, arr2);
	printf("%s", arr1); //结果为abcdef

	return 0;
}

2.3模拟实现📘

#include <stdio.h>
#include<assert.h>

char* my_strcpy( char* des, const char*src)
{
	assert(des && src); //断言判断des和src是否时空指针
	char* ret = des; //将des的首地址赋给ret用来最后返回,因为des在++后不再指向首地址
	while (*des++ = *src++) //依次将字符赋给des直到'\0'循环终止
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = { 0 };
	char* ret = my_strcpy(arr2, arr1);

	printf("%s", ret);
	return 0;
}

3.strcat📚

3.1函数用法📗

strcat函数用来追加字符串,将源数组加到目标数组的末尾,即从目标数组的'\0'位置处开始追加;和strcpy函数需要注意的点一样:

  • 源数组必须有'\0'
  • 目标数组的空间必须足够大
  • 目标数组必须可变,不能是常量字符串

strcat函数原型:

返回类型为char*,destination用来接收目标数组的地址,source用来接收源数组的地址

3.2具体实现📕

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

int main()
{
	char arr1[20] = "abc"; //目标空间必须足够大
	char arr2[] = "def";
	strcat(arr1, arr2);
	printf("%s", arr1); //结果为abcdef

	return 0;
}

3.3模拟实现📘

#include<stdio.h>
#include<assert.h>

char* my_strcat(char* des, const char* src)
{
	assert(des && src); //断言判断des和src是否为空指针
	char* ret = des;
	while (*des != '\0') //先找到目标数组'\0'的位置
	{
		des++;
	}
	while (*des++ = *src++) //从目标数组的'\0'位置处开始依次将源数组拷贝到目标数组
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[20] = "abc";
	char arr2[] = "def";
	char* ret = my_strcat(arr1, arr2);

	printf("%s", ret);
	return 0;
}


4.strcmp📚

4.1函数用法📗

strcmp函数用来比较字符串,从两个字符串的第一个字符开始依次比较它们的ASCII码值,只要出现一个字符大于另一个字符就停止比较,此时较大字符所在的字符串大于另一个字符串

strcmp函数原型:

str1和str2分别接收要比较的两个数组的地址,返回类型为int,str1>str2则返回一个大于0的数,str1<str2则返回一个小于0的数,str1=str2则返回0

4.2具体实现📕

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

int main()
{
	char arr1[] = "abcfff";
	char arr2[] = "abczz";
	int cmp = my_strcmp(arr1, arr2);
	if (cmp > 0)
	{
		printf(">");    
	}
	else              
	{
		printf("<="); //结果为<=,因为f<z
	}

	return 0;
}

4.3模拟实现📘

#include<stdio.h>
#include<assert.h>

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1++ == *str2++) //依次比较两字符串的字符
	{
		if (*str1 == '\0' && *str2 == '\0')
		{
			return 0; //若两字符串的字符一直到'\0'都相等,则相等,返回0
		}
	}
	return *str1 - *str2; //*str1大返回大于0的数,否则返回小于0的数
}

int main()
{
	char arr1[] = "abcfff";
	char arr2[] = "abczz";

	int cmp = my_strcmp(arr1, arr2);
	if (cmp > 0)
	{
		printf(">");
	}
	else
	{
		printf("<=");
	}
	return 0;
}

5.strncpy📚

5.1函数用法📗

strncpy函数原型:

这里相较于strcpy多了一个参数num

用法:和strcpy用法相同,但它是将源数组的前num个字符拷贝到目标数组中

5.2具体实现📕

#include<stdio.h>

int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = { 0 };
	size_t num = 3;

	strncpy(arr2, arr1, num); //将arr1的前三个字符拷贝到arr2中
	printf("%s", arr2);  //结果为abc
	
	return 0;
}

5.3模拟实现📘

和strcpy的模拟实现类似,只不过要加一条对n的判断以确保只拷贝前n个字符

#include<stdio.h>
#include<assert.h>

char* my_strncpy(char* des, const char* src, size_t n)
{
	assert(des && src);
	char* ret = des;

	while (*des++ = *src++)
	{
		n--;
		if (n == 0)  
		{
			return ret;
		}
	}
}

int main()
{
	char arr1[] = "abcedf";
	char arr2[20] = { 0 };
	size_t num = 3;

	char* r = my_strncpy(arr2, arr1, num);

	printf("%s", r);
	return 0;
}

6.strncat📚

6.1函数用法📗

strncat函数原型:

用法:和strncat函数用法相同,但它是将数组的前num个字符追加到目标数组的'\0'处

6.2具体实现📕

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

int main()
{
	char arr1[20] = "abc\0xxx";
	char arr2[] = "defghi";
	size_t num = 3;

	strncat(arr1, arr2, num); //加完后会自动将\0加上
	printf("%s", arr1);
	return 0;
}

在arr1的'\0'处将def加上后会自动加一个'\0'以构成一个完整的字符串

6.2模拟实现📘

和strcat的模拟实现类似,只不过要加一条对n的判断以确保只追加前n个字符

#include<stdio.h>
#include<assert.h>

char* my_strncat(char* des, const char* src, size_t n)
{
	char* ret = des;
	while (*des != '\0')
	{
		des++;
	}
	while (*des++ = *src++)
	{
		n--;
		if (n == 0)
		{
			*des = '\0';
			return ret;
		}
	}
}

int main()
{
	char arr1[20] = "abc";
	char arr2[] = "defghi";
	size_t num = 3;

	char* ret = my_strncat(arr1, arr2, num);

	printf("%s", ret);
	return 0;
}

7.strncmp📚

7.1函数用法📗

strncmp函数原型:

用法:和strcmp用法相同,但它只比较两个字符串前num个字符

7.1具体实现📕

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

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdzz";
	size_t num = 0;

	int cmp = strncmp(arr1, arr2, num);
	if (cmp > 0)
	{
		printf(">");
	}
	else
	{
		printf("<=");
	}

	return 0;
}

7.3模拟实现📘

#include<stdio.h>
#include<assert.h>

int my_strncmp(const char* str1, const char* str2, size_t n)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		n--;
		if (n == 0)
		{
			return 0; //当前n个字符相同,返回0
		}
	}
	return *str1 - *str2; //出现字符不相同时,跳出上面循环,返回*str1 - *str2
//前者大,返回大于0的值,后者大,返回小于0的值

}

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdzz";
	size_t num = 3;

	int cmp = my_strncmp(arr1, arr2, num);
	if (cmp > 0)
	{
		printf(">");
	}
	else
	{
		printf("<=");
	}

	return 0;
}

🙉以上为7个字符串库函数的讲解,后续会对剩余的字符串库函数和内存函数进行讲解

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

荣膺ODCC 三项大奖!记忆科技旗下忆联再获行业认可

9月13—14日&#xff0c;由开放数据中心委员会&#xff08;ODCC&#xff09;举办的“2023 ODCC开放数据中心大会” 在北京举办。忆联母公司记忆科技作为国内领先IT硬件厂商受邀参会&#xff0c;以一站式成果为在场嘉宾带来一场科技盛宴。在本次大会中&#xff0c;忆联凭借极具竞…

华为MTL流程的六个模块初步解析

大家好&#xff01; 昨天华研荟给大家介绍了华为MTL流程的基本概念和发展历程&#xff0c;今天我们来了解下华为MTL流程的六个模块。 如昨天所述&#xff0c;华为的MLT流程主要有六个模块&#xff1a;市场洞察、市场管理、联合创新、销售赋能、激发需求、营销质量管理。 接下…

Spring 工厂

目录 一、Spring 工厂创建复杂对象 1、什么是复杂对象 2、 Spring 工厂创建复杂对象的 3 种方式 &#xff08;1&#xff09;FactoryBean 接口 开发步骤&#xff1a; 细节&#xff1a; FactoryBean 的实现原理[简易版] Factory Bean 总结 &#xff08;2&#xff09;实例…

IGEV深度估计测试代码

生成点云的测试脚本&#xff1a; import sys sys.path.append(core) DEVICE cuda import osos.environ[CUDA_VISIBLE_DEVICES] 0 import argparse import glob import numpy as np import torch from tqdm import tqdm from pathlib import Path from igev_stereo import IG…

2020-2023小样本学习(FSL)顶会论文及开源代码合集(已分类整理)

这次分享的是近四年&#xff08;2020-2023&#xff09;各大顶会中的小样本学习&#xff08;FSL&#xff09;论文&#xff0c;有160篇&#xff0c;涵盖了FSL三大类方法&#xff1a;数据、模型、算法&#xff0c;以及FSL的应用、技术、理论等领域。 由于论文数量太多&#xff0c…

【文末赠书】SRE求职必会 —— 可观测性平台可观测性工程(Observability Engineering)

文章目录 〇、导读一、实现可观测性平台的技术要点是什么&#xff1f;二、兼容全域信号量三、所谓全域信号量有哪些&#xff1f;四、统一采集和上传工具五、统一的存储后台六、自由探索和综合使用数据七、总结★推荐阅读《可观测性工程》直播预告直播主题直播时间预约直播 视频…

福建厦门航空飞机发动机零部件检测3D测量尺寸偏差比对-CASAIM中科广电

航空航天是一个创新型发展国家的尖端命脉&#xff0c;代表着一个国家科学技术的先进水平。在航空航天工业的发展和组成领域中&#xff0c;对于在制造业中的航空航天产品零部件精度要求十分严苛&#xff0c;从前期的设计、中期建造、后期维修检测&#xff0c;任何一个环节、任何…

vue一直自动换行问题解决

html换行主要是由于< div >标签引起的&#xff0c;而vue的一些前端组件本身就会自带< div >&#xff0c;比如el-input的标签拆分出来之后就形成了如下的内容 因此之前我采用 <el-form-item prop"code" v-if"captchaOnOff"><el-inpu…

【算法挨揍日记】day06——1004. 最大连续1的个数 III、1658. 将 x 减到 0 的最小操作数

1004. 最大连续1的个数 III 1004. 最大连续1的个数 III 题目描述&#xff1a; 给定一个二进制数组 nums 和一个整数 k&#xff0c;如果可以翻转最多 k 个 0 &#xff0c;则返回 数组中连续 1 的最大个数 。 解题思路&#xff1a; 首先题目要我们求出的最多翻转k个0后&#x…

BMS电池管理系统的蓝牙芯片 国产高性能 低功耗蓝牙Soc芯片PHY6222

电池管理系统是对电池进行监控与控制的系统&#xff0c;将采集的电池信息实时反馈给用户&#xff0c;同时根据采集的信息调节参数&#xff0c;充分发挥电池的性能。但是&#xff0c;前技术中&#xff0c;在管理多个电池时&#xff0c;需要人员现场调试与设置&#xff0c;导致其…

优化Java代码效率和算法设计,提升性能

在Java开发中&#xff0c;代码效率低下和算法不合理可能导致程序性能下降。下面将从以下几个方面探讨如何优化Java代码和算法设计&#xff0c;以提高程序的性能&#xff1a; 通过这些优化策略&#xff0c;我们可以显著提升Java程序的性能和响应速度。 一、选择合适的数据结构…

这个库,让Python与Excel完美结合

迷途小书童 读完需要 5分钟 速读仅需 2 分钟 1 简介 在现代数据分析和处理中&#xff0c;Python 和 Excel 都扮演着非常重要的角色。如果&#xff0c;能将这两者无缝结合在一起并发挥它们各自的优势&#xff0c;是一个令人兴奋的想法。幸运的是&#xff0c;PyXLL 这个 Excel 插…

Biome-BGC生态系统模型与Python融合技术

Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数&#xff0c;模拟日尺度碳、水和氮通量的有效模型&#xff0c;其研究的空间尺度可以从点尺度扩展到陆地生态系统。 在Biome-BGC模型中&#xff0c;对于碳的生物量积累&#xff0c;采用光合酶促反应机理模型计算出每天…

如何实现在本地 Linux 主机上实现对企业级夜莺监控分析工具的远程连接

文章目录 前言1. Linux 部署Nightingale2. 本地访问测试3. Linux 安装cpolar4. 配置Nightingale公网访问地址5. 公网远程访问Nightingale管理界面6. 固定Nightingale公网地址 前言 夜莺监控是一款开源云原生观测分析工具&#xff0c;采用 All-in-One 的设计理念&#xff0c;集…

构建无缝的服务网格体验:分享在生产环境中构建和管理服务网格的最佳实践

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Java的序列化

写在前面 本文看下序列化和反序列化相关的内容。 源码 。 1&#xff1a;为什么&#xff0c;什么是序列化和反序列化 Java对象是在jvm的堆中的&#xff0c;而堆其实就是一块内存&#xff0c;如果jvm重启数据将会丢失&#xff0c;当我们希望jvm重启也不要丢失某些对象&#xff…

Linux学习-Redis主从和哨兵

主从复制 一主一从结构 # 配置host61为主服务器 [roothost61 ~]# yum -y install redis [roothost61 ~]# vim /etc/redis.conf bind 192.168.88.61 #设置服务使用的Ip地址 port 6379 #设置服务使用的端口号 使用默认端口即可 [roothost61 ~]# systemctl start redis [rooth…

深入探索图像处理:从基础到高级应用

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 图像处理是计算机视觉领…

高数(上) 第一章:函数、极限、连续

文章目录 一、函数1.函数的概念、基本初等函数2.函数的性质 /函数四性态1.单调性2.奇偶性(3)导函数的奇偶性 3.周期性4.有界性5.对称性 3.基本不等式4.开根要带绝对值 二、极限1.极限的概念①数列极限②函数极限需要区分左右极限的三种问题 &#xff08;左右极限有区别&#xf…

[网鼎杯 2020 朱雀组]Nmap 通过nmap写入木马 argcmd过滤实现逃逸

这道题也很好玩 啊 原本以为是ssrf 或者会不会是rce 结果是通过nmap写入木马 我们来玩一下 传入木马 映入眼帘是nmap 我们首先就要了解nmap的指令 Nmap 相关参数-iL 读取文件内容&#xff0c;以文件内容作为搜索目标 -o 输出到文件-oN 标准保存-oX XML保存-oG Grep保存-oA…