字符串函数内存函数(从零到一)【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;//找到源字符串中的\0while (*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函数只能设置为整数值,不能设置为其他类型的值。 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能优化算法应用:基于饥饿游戏算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于饥饿游戏算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于饥饿游戏算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.饥饿游戏算法4.实验参数设定5.算法结果6.…

xcode无线真机调试详细图文步骤

步骤一、 步骤二&#xff1a; 步骤三&#xff1a; 配置完到这里&#xff0c;点击真机右键&#xff0c;菜单栏并未出现connect via ip address 选项&#xff0c;也没出现无线连接的小地球图标&#xff0c;别慌&#xff0c;接着进行下一步操作即可。 步骤四&#xff1a; 1.打开…

【Linux】冯诺依曼体系结构与操作系统及其进程

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解冯诺依曼体系结构与操作系统&#xff0c;掌握…

使用ultralytics(YOLOv8)实现RT-Detr

b站视频&#xff1a;https://www.bilibili.com/video/BV12C4y1S75H/ 1 使用ultralytics&#xff08;YOLOv8&#xff09;实现RT-Detr https://github.com/ultralytics/ultralytics/blob/a5735724c54a9f5bcb239c151fefbd1337d7123d/docs/zh/models/rtdetr.md 2 安装 YOLOv8安装…

分享一个项目——Sambert UI 声音克隆

文章目录 前言一、运行ipynb二、数据标注三、训练四、生成总结 前言 原教程视频 项目链接 运行一个ipynb&#xff0c;就可操作 总共四步 1&#xff09;运行ipynb 2&#xff09;数据标注 3&#xff09;训练 4&#xff09;生成 一、运行ipynb 等运行完毕后&#xff0c;获得该…

【powershell】Windows环境powershell 运维之历史文件压缩清理

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&am…

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

目录 12.4.2 在屏幕上绘制飞船 alien_invasion.py ​编辑12.5 重构&#xff1a;模块 game_functions 12.5.1 函数 check_events() game_functions.py alien_invasion.py 12.5.2 函数 update_screen() game_functions.py alien_invasion.py 12.6 驾驶飞船 12.6.1 响应…

虚拟机类加载机制

虚拟机类加载机制 什么是虚拟机的类加载机制&#xff1f; Java虚拟机将描述类的Class文件加载到内存中&#xff0c;并对数据进行校验、转换解析和初始化&#xff0c;最终形成可以被虚拟机直接使用的Java类型&#xff0c;这个过程叫做虚拟机的类加载机制 类加载的时机 一个类…

【MATLAB】史上最全的25种信号分解算法全家桶

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 1 【MATLAB】EMD 信号分解算法 EMD 是一种信号分解方法&#xff0c;它将一个信号分解成有限个本质模态函数 (EMD) 的和&#xff0c;每个 EMD 都是具有局部特征的振动模式。EMD 分解的主要步骤如下&#xff1a; 将信号的…

机器学习数据的清洗,转化,汇总及建模完整步骤(基于Titanic数据集)

目录 介绍&#xff1a; 一、数据 二、检查数据缺失 三、数据分析 四、数据清洗 五、数据类别转化 六、数据汇总和整理 七、建模 介绍&#xff1a; 线性回归是一种常用的机器学习方法&#xff0c;用于建立一个输入变量与输出变量之间线性关系的预测模型。线性回归的目标…

3-10岁孩子语文能力培养里程碑

文章目录 基础能力3岁4岁5岁6-7岁&#xff08;1-2年级&#xff09;8-9岁&#xff08;3-4年级&#xff09;10岁&#xff08;5年级&#xff09; 阅读推荐&父母执行3岁4-5岁6-7岁&#xff08;1-2年级&#xff09;8-9岁&#xff08;3-4年级&#xff09;10岁&#xff08;5年级&a…

Elasticsearch:什么是文本分类?

文本分类定义 - text classification 文本分类是一种机器学习&#xff0c;它将文本文档或句子分类为预定义的类或类别。 它分析文本的内容和含义&#xff0c;然后使用文本标签为其分配最合适的标签。 文本分类的实际应用包括情绪分析&#xff08;确定评论中的正面或负面情绪&…

Linux操作系统(ACL)

ACL (针对特殊用户的特殊权限) 访问控制列表&#xff0c;可以针对文件和目录 ACL的真正效果主要体现在对文件的操作上 1. 如何查看ACL信息&#xff1a;getfacl 文件名(文件路径) 2. 如何设置普通文件ACL信息&#xff1a;setfacl -m u:用户名&#xff1a;权限 文件名 现在要求…

JVM垃圾收集器三色标记算法

垃圾收集算法 分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法&#xff0c;这种算法没有什么新的思想&#xff0c;只是根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代&#xff0c;这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。 比…

NFT获工信部首肯!“符合中国国情”的Web3.0发展战略即将问世!

今年3月&#xff0c;香港立法会议员吴杰庄在出席中国全国两会时&#xff0c;提出《关于推动Web3.0产业发展的提案》&#xff0c;针对中国加强Web3.0技术研发、建立标准和培养人才等几方面提岀意见。 本月19日&#xff0c;中国工信部针对该提案提交答复&#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…

【智慧之窗】AI驱动产品探索

一.初识 ChatGPT ChatGPT 是由 OpenAI 开发的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;基于 GPT&#xff08;Generative Pre-trained Transformer&#xff09;架构。GPT 系列的模型旨在理解和生成自然语言文本。ChatGPT 专注于支持对话性任务&#xff0c;即与…

如何通过ETLCloud的API对接功能实现各种SaaS平台数据对接

前言 当前使用SaaS系统的企业越来越多&#xff0c;当我们需要对SaaS系统中产生的数据进行分析和对接时就需要与SaaS系统提供的API进行对接&#xff0c;因为SaaS一般是不会提供数据库表给企业&#xff0c;这时就应该使用ETL&#xff08;Extract, Transform, Load&#xff09;的…

Spring MVC控制层框架

三、Spring MVC控制层框架 目录 一、SpringMVC简介和体验 1. 介绍2. 主要作用3. 核心组件和调用流程理解4. 快速体验 二、SpringMVC接收数据 1. 访问路径设置2. 接收参数&#xff08;重点&#xff09; 2.1 param 和 json参数比较2.2 param参数接收2.3 路径 参数接收2.4 json参…

Opencv入门五 (显示图片灰度值)

源码如下&#xff1a; #include <opencv2/opencv.hpp> int main(int argc, char** argv) { cv::Mat img_rgb, img_gry, img_cny; cv::namedWindow("Example Gray",cv::WINDOW_AUTOSIZE); cv::namedWindow("Example Canny", cv::WINDOW_…