字符串函数内存函数(从零到一)【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.mzph.cn/news/235520.shtml

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

相关文章

深度学习模型压缩方法:剪枝方法分类介绍

本文将介绍深度学习模型压缩方法中的剪枝,内容从剪枝简介、剪枝步骤、结构化剪枝与非结构化剪枝、静态剪枝与动态剪枝、硬剪枝与软剪枝等五个部分展开。 一、剪枝简介 在介绍剪枝之前,首先介绍过参数化这个概念,过参数化主要是指在训练阶段,在数学上需要进行大量的微分求解…

二维码智慧门牌管理系统:实现数据通信安全

文章目录 前言一、传输隧道加密技术二、传输数据加密技术三、数据接入鉴权技术 前言 随着信息技术的蓬勃发展&#xff0c;智慧门牌管理系统已成为现代商业和家庭重要的一部分。然而&#xff0c;系统普及的同时也带来了数据通信安全的突出问题。为了解决这一挑战&#xff0c;二…

Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读

文章目录 概念概述StringEncoderStringDecoder Code源码分析StringEncoderStringDecoder 小结 概念 概述 Netty是一个高性能的网络应用程序框架&#xff0c;它提供了丰富的功能&#xff0c;包括编解码器&#xff0c;这些编解码器用于在网络中发送和接收数据时进行数据的编码和…

SOME/IP SubscriberEventGroup

1 SOME/IP SubscriberEventGroup SubscriberEventGroup是SOME/IP中的一种服务发现和注册的消息类型,它用于让服务使用者订阅服务提供者的事件组。 事件组是一种将服务的方法和字段分组的方式,它可以让服务使用者只接收感兴趣的数据,而不是所有的数据。 SubscriberEventGrou…

nodejs+vue+微信小程序+python+PHP柚子校园影院系统-计算机毕业设计推荐

柚子校园影院综合网络空间开发设计要求。目的是将系统传统管理方式转换为在网上管理&#xff0c;完成信息管理的方便快捷、安全性高、交易规范做了保障&#xff0c;目标明确。柚子校园影院可以将功能划分为管理员功能和用户功能。  而开发本系统&#xff0c;又能够提高系统整体…

在 Windows 搭建 SVN 服务

近公司给配了台新电脑&#xff0c;配置挺主流的&#xff0c;但是不舍得抛弃自己的旧电脑&#xff08;原配嘛&#xff0c;这叫贪新不舍旧&#xff09;&#xff0c;于是打算在新电脑上只作开发环境&#xff0c;然后旧电脑作为版本库&#xff0c;这样保存版本的时候可以直接上传到…

es、MySQL 深度分页问题

文章目录 es 深度分页MySQL 深度分页 es 深度分页 es 深度分页问题&#xff0c;有点忘记了&#xff0c;这里记录一下 当索引库中有10w条数据&#xff0c;比如是商品数据&#xff1b;用户就是要查在1w到后10条数据&#xff0c;怎么查询。 es查询是从各个分片中取出前1w到后10条数…

LeetCode 19 删除链表的倒数第 N 个结点

题目描述 删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1…

列举mfc140u.dll丢失的解决方法,常见的mfc140u.dll问题

在使用电脑的过程中&#xff0c;有时会遇到mfc140u.dll文件丢失的问题&#xff0c;导致一些应用程序无法正常启动。本文将介绍mfc140u.dll丢失的常见原因&#xff0c;并提供相应的解决办法。同时&#xff0c;还会列举一些与mfc140u.dll丢失相关的常见问题和解答。 第一部分&…

【qt信号槽-5】信号槽相关注意事项记录

背景&#xff1a; 信号槽是qt很重要的概念&#xff0c;遇到问题帮助没少看。其中就有signals and slots这一章节&#xff0c;说得很到位。 概念琐碎&#xff0c;记录备忘。不对之处望指正。 【qt信号槽-1】槽函数重写问题&#xff0c;qt_metacall和qt_static_metacall-CSDN博…

动力电池系统介绍(十四)——热管理系统

动力电池系统介绍&#xff08;十四&#xff09; 一、梗概二、座舱热管理&#xff08;汽车空调&#xff09;2.1 空调制冷2.2 空调制热2.2.1 传统燃油汽车空调制热2.2.2 新能源汽车空调制热 三、动力系统热管理3.1 燃油车发动机热管理3.1.1 冷却系统3.1.2 润滑系统3.1.3 进排气系…

【QT】Model/View结构

目录 1 概述 2 Mode/View基本原理 3 数据模型 4 视图组件 5 代理 6 Model/View结构的一些概念 6.1 Model/View的基本结构 6.2 模型索引 6.3 行号和列号 6.4 父项 6.5 项的角色 1 概述 Model/View&#xff08;模型/视图&#xff09;结构是Qt中用界面组件显示与编辑数据的一种结构…

算法基础之筛质数

筛质数 核心思想&#xff1a;筛法求质数 埃氏筛法: 每次用 2 3 4…. p-1 筛 2 - p之间的数出现2 3 4 …的倍数时 去掉(4实际已经被去掉 不会用4去筛)当2~p-1的数都没有筛掉p 说明p是质数 优化: 只用2~p-1中质数筛 线性筛法: 核心: n只会被其最小质因子筛掉 每一个合数都只…

MFC 消息映射机制

目录 消息映射机制概述 宏展开 宏展开的作用 消息映射机制的执行流程 消息处理 消息映射机制概述 MFC的消息映射映射机制是可以在不重写WindowProc虚函数的大前提下&#xff0c;仍然可以处理消息。 类必须具备的要件 类内必须添加声明宏 DECLARE_MESSAGE_MAP() 类外…

linux 应用开发笔记---【线程】

1.概念&#xff1a; 线程是参与系统调度的最小单位&#xff0c;它被包含在进程中&#xff0c;是进程的实际运行单位 一个进程可以创建多个线程&#xff0c;多个线程并发运行&#xff0c;每个线程执行不同的任务 2.如何创建线程 当一个程序启动的时候&#xff0c;一个进程被…

Cesium 3DTiles数据格式详解

目录 0 引言1 3DTiles1.1 起源1.2 后缀类型及特点1.2.1 b3dm1.2.2 i3dm1.2.3 pnts1.2.4 cmpt1.2.5 json1.2.6 总结 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;CesiumforUnreal专栏&#x1f4a5; 标题&#xff1a;Cesium 3DTiles数据格式详解❣…

【Netty】Netty核心API及使用

目录 Netty核心APIChannelHandler及其实现类ChannelPipelineChannelHandlerContextChannelOptionChannelFutureEventLoopGroup和实现类NioEventLoopGroupServerBootstrap和BootstrapUnpooled类 Netty入门案例引入依赖Netty服务端编写Netty客户端编写 Netty核心API ChannelHand…

智能优化算法应用:基于龙格-库塔算法3D无线传感器网络(WSN)覆盖优化 - 附代码

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

FPGA模块——以太网芯片MDIO读写

FPGA模块——以太网MDIO读写 MDIO接口介绍MDIO接口代码&#xff08;1&#xff09;MDIO接口驱动代码&#xff08;2&#xff09;使用MDIO驱动的代码 MDIO接口介绍 MDIO是串行管理接口。MAC 和 PHY 芯片有一个配置接口&#xff0c;即 MDIO 接口&#xff0c;可以配置 PHY 芯片的工…

读书笔记产品经理学习笔记1-忘掉技术,先看客户需求

技术到产品思维的转换 以前做技术的时候&#xff0c;扮演的角色是怎样多快好省的完成开发。现在做产品了&#xff0c;你得自己定产品方案&#xff0c;让别人来开发。最重要的是先弄清楚客户的需求是什么&#xff0c;要解决什么问题&#xff0c;再看产品怎么设计&#xff0c;然…