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;
}

结语:

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

相关推荐
派大鑫wink2 小时前
【Day1】Java 入门:开发环境搭建(JDK 安装 + IDEA 配置 + HelloWorld 实战)
java·开发语言·intellij-idea
lsx2024062 小时前
R JSON 文件
开发语言
hudawei9962 小时前
kotlin冷流热流的区别
android·开发语言·kotlin·flow··冷流·热流
moxiaoran57532 小时前
Go语言的map
开发语言·后端·golang
小信啊啊2 小时前
Go语言数组
开发语言·后端·golang
qq_336313932 小时前
Java基础-Stream流
java·开发语言·windows
superman超哥2 小时前
仓颉语言中异常捕获机制的深度剖析与工程实践
c语言·开发语言·后端·python·仓颉
再__努力1点2 小时前
【76】Haar特征的Adaboost级联人脸检测全解析及python实现
开发语言·图像处理·人工智能·python·算法·计算机视觉·人脸检测