C语言内存函数详解

目录

引言:

1.memcpy函数

1.1.memcpy函数的使用

1.2.memcpy函数的模拟实现

2.memmove函数

2.1.memmove函数的使用

2.2.memmove函数的模拟实现

3.memset函数

3.1.memset函数的使用

3.2.memset函数的模拟实现

4.memcmp函数

4.1.memcmp函数的使用

4.2.memcmp函数的模拟实现

结语:


引言:

在上一篇文章中,我们已经讲解了如何使用对字符串操作的库函数,已经如何去模拟实现那些函数,那么,如果我们想要进行拷贝或比较操作的是别的类型的数组呢,那么,这个时候就要用到我们C语言库中的内存函数了

那么,话不多说,接下来我们进入内存函数详解正篇------------------>

1.memcpy函数

cpp 复制代码
void * memcpy ( void * destination, const void * source, size_t num );

memcpy和strcnpy其实是大差不大的,strncpy的功能是将源字符串的num个字母拷贝到目标字符串中

memcpy就是将原数组中的num个字节拷贝到目标数组中

因为字符串也是数组,所以memcpy会了后,用memcpy替代strncpy来拷贝字符串也是可以的

1.1.memcpy函数的使用

特别注意:这个函数在遇到\0的时候并不会停下来

如果原内存和目标空间有重叠的话,复制的结果就是未定义的(为什么会未定义可以通过看模拟实现知道缘由)如果涉及空间重叠部分的拷贝,就要使用memmove函数

附:VS的memcpy函数是可以实现重叠空间的拷贝的,其实原理就是将memcpy优化的跟memmove差不多

memcpy函数拷贝结束后返回的值是目标空间的首地址

那么我们来举例如何使用memcpy,代码如下

cpp 复制代码
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 20);

上述代码中源空间就是arr1,目标空间就是arr2,就是讲arr1中的20个字节全部复制给arr2,注意是字节,所以arr2拷贝完是1,2,3,4,5

1.2.memcpy函数的模拟实现

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <assert.h>

void* my_memcpy(void* p1,void* p2,int cnt)
{
    assert(p1&&p2);
    char* P1 = (char*)p1;
    char* P2 = (char*)p2;
    while(cnt--)
    {
        *P1++ = *P2++;
    }
    return p1;
}

int main()
{
    long long a[10] = {0};
    long long b[10] = {1,2,3,4,5};
    my_memcpy(a,b,4*sizeof(b[0]));
    for(int i = 0;i<10;i++)
    {
        printf("%lld", a[i]);
    }
    return 0;
}

2.memmove函数

cpp 复制代码
void * memmove ( void * destination, const void * source, size_t num );

2.1.memmove函数的使用

memmove函数跟memcpy函数实现的功能是一样的,就是多了可以有重复空间的拷贝,返回的类型和返回的是什么跟memcpy是一样的,参数使用也是跟memcpy一样的,所以使用就不讲了,直接就讲模拟实现啦

2.2.memmove函数的模拟实现

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <assert.h>

void* my_memmove(void* p1,void* p2,int cnt)
{
    assert(p1&&p2);
    char* P1 = (char*)p1;
    char* P2 = (char*)p2;
    if(P1>=P2)
    {
        while(cnt--)
            *(P1+cnt)=*(P2+cnt);
    }
    else
    {    
        while(cnt--)
            *P1++ = *P2++;
    }
    return p1;
}

int main()
{
    long long a[10]  = {1,2,3,4,5,6,7,8,9,10};
    my_memmove(a,a+1,5*sizeof(a[0]));
    for(int i = 0;i<10;i++)
    {
        printf("%lld", a[i]);
    }
    return 0;
}

3.memset函数

cpp 复制代码
void * memset ( void * ptr, int value, size_t num );

这个函数是用来设置内存的,将内存中的值以字节为单位设置成想要的内容

这个函数的返回值就是目标空间的首地址

3.1.memset函数的使用

这里就直接举个例子,代码如下

cpp 复制代码
#include <stdio.h>
#include <string.h>
int main ()
{
    char str[] = "hello world";
    memset (str,'x',6);
    printf(str);
    return 0;
}

这个就是将从str这个地址开始及往后的6个字节全都设成x,因为是char类型,所以改一个字节就是改一个字符,所以改完后输出结果就是如下了

xxxxxxworld

但我们在平常使用的时候,应该这个是你们见的最多的,代码如下

cpp 复制代码
int a[10];
int b[10];
memset(a,0,sizeof(a));
memset(b,0x3f,sizeof(b));

一个是将a数组的所有字节都改为0,那么就是将数组清0

一个是将b数组的所有字节都改为3f,那么一个元素的大小就是0x3f3f3f3f,也相当于是把数组 元素重置为无限大

那么,使用讲完了,我们来讲讲如何模拟实现

3.2.memset函数的模拟实现

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include <assert.h>

void* my_memset(void* p1,int x,int cnt)
{
    for(int i = 0;i<cnt;i++)
    {
        *((char*)p1+i)=x;
    }
    return p1;
}

4.memcmp函数

cpp 复制代码
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

这个函数其实跟strncmp函数差不多,就是比较源空间和目标空间前num个字节,比较原理就跟strncmp函数是一样的,这里就不过多赘述了

4.1.memcmp函数的使用

cpp 复制代码
#include <stdio.h>
#include <string.h>
int main()
{
 char buffer1[] = "DWgaOtP12df0";
 char buffer2[] = "DWGAOTP12DF0";
 int n;
 n = memcmp(buffer1, buffer2, sizeof(buffer1));
 if (n > 0) 
 printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
 else if (n < 0) 
 printf("'%s' is less than '%s'.\n", buffer1, buffer2);
 else 
 printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
 return 0;
}

4.2.memcmp函数的模拟实现

cpp 复制代码
int mt_memcmp(const void* p1,const void* p2,int cnt)
{
    char* P1 = (char*)p1;
    char* P2 = (char*)p2;
    while(cnt--)
    {
        if(*P1>*P2)
            return 1;
        if(*P1++ <*P2++)
            return -1;
    }
    return 0;
}

结语:

希望以上内容对你有所帮助,感谢观看,若觉得写的还可以,可以分享给朋友一起来看哦,毕竟一起进步更有动力嘛

相关推荐
第九序言T7 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
龙亘川8 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
程序喵大人8 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
Raas1009 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
专注仿真10 小时前
线性回归和逻辑回归算法详解
开发语言·人工智能·python·大模型训练·控制算法
jimy110 小时前
C++ 中的 `T&&`:右值引用与转发引用
开发语言·c++
呆呆虫1211 小时前
用 orjson 加速 SerpBase 响应解析:基准对比与注意事项
开发语言·php
心疼你的一切11 小时前
Python自动发邮件实战定时发报表
大数据·开发语言·python
Zwawa12 小时前
串口为什么会丢字节:从轮询到中断和环形缓冲区
c语言·单片机·嵌入式
Wang's Blog12 小时前
Java 项目实战:交友项目 - 用户体系集成总结
java·开发语言·交友