10分钟让你学会内存函数:memcpy,memmove,memset,memcmp的用法及模拟实现。

简介: 10分钟让你学会内存函数:memcpy,memmove,memset,memcmp的用法及模拟实现。

目录:内存操作函数

一:memcpy函数(内存拷贝)

二:memmove函数(内存拷贝)

三:memset函数(内存设置)

四:memcmp函数(内存比较)


一:memcpy函数

memcpy内存函数的实现原理:                                                                                                    

将 num 个字节的数据从 source 指向的位置开始拷贝到 destination 指向的内存块中,这个函数在遇到0’的时候并不会停下

所以memcpy函数中需要传入三个参数,分别是目标内存空间的首地址,被拷贝内存空间的首地址和拷贝字节数。

memcpy函数可以拷贝字符串数据,整形数组数据,结构体数据等诸多类型......,但因为memcpy内存函数不能够自身拷贝,memcpy函数不能够拷贝内存重叠区的数据,因此存在着一定的局限性,在这里,小夏推荐大家在遇到数据拷贝时应用接下来的memmove函数可以完美的避免所有的不稳定因素。


二:memmove函数

memmove内存函数的实现原理(内存存在重叠,无重叠都可使用):

用于拷贝内存数据,如果目标区域和源区域有重叠的话,

memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中

但复制后源内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同

memmove函数实现重叠内存过程:

总结来说,在遇到内存重叠的情况下分为三中情况:

1.从前向后拷贝(内存空间存在重叠)->如果source的地址高于disnation的地址:则进行常规的赋值,及从source的地址依次向后对disnation地址进行拷贝,直到拷贝的字节数达到size_t num,及拷贝完成。

2.从后向前拷贝(内存空间存在重叠)->如果source的地址低于disnation的地址:则进行逆序的赋值,及从source+num的地址向前对disnation+num地址进行拷贝,直到拷贝的字节数达到size_t num,及拷贝完成。

3.从前向后拷贝或-从后向前拷贝都可(内存空间不存在重叠)


模拟实现memmove函数:

我们可以自己写一个my_memmove函数来模拟实现memmove函数的功能

首先定义函数void* my_memmove(void* s1, const void* s2, size_t len)

因为memmove是拷贝内存的函数,对于内存中被拷贝的是什么数据类型,并没有限制,所以传入的参数数据类型用void*,返回值也是无类型的地址。

size_len是一个无符号整数类型,表示想要拷贝的字节数,所以在my_memmove函数内部,我们可以这样写

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* s1, const void* s2, size_t len)
{
  assert(s1);
  assert(s2);
  void* ret = s1;
  int i = 0;
  
  if (((char*)s2)>((char*)s1))//从s2的前端依次拷贝
  {
    for(i=0;i<len;i++)
    {
      *((char*)s1) = *((char*)s2);
      (char*)s1 = (char*)s1 + 1;
      (char*)s2 = (char*)s2 + 1;
    }
  }
  else
  {
    while (len--)//从s2的后端开始拷贝
      {
        *((char*)s1 + len) = *((char*)s2 + len);
      }
  }
 
  return ret;
}
int main()
{
  
  int arr[20] = { 0 };
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    arr[i] = i + 1;
  }
  my_memmove(arr + 1, arr , sizeof(int) * 5);
  for (i = 0; arr[i] != 0; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
}


三:memset函数

memset内存函数的实现原理:num字节对内存块进行初始化

将value的值依次从ptr地址,依次向后size_t num个字节的内存空间进行赋值


memset的函数定义:

模拟实现memset函数:

我们可以自己写一个my_memset函数来模拟实现memset函数的功能

首先定义函数void* my_memset(void * ptr, int value, size_t num)

因为memset是拷贝内存的函数,对于内存中被拷贝的是什么数据类型,并没有限制,所以传入的参数数据类型用void*,返回值也是无类型的地址。

size_num是一个无符号整数类型,表示想要赋值的字节数,所以在my_memset函数内部,我们可以这样写

#include<stdio.h>
void* my_memset(void* ptr, int value, size_t num)
{
  while (num--)
  {
    *((char*)ptr) = value + '0';
    ptr = (char*)ptr + 1;
  }
}
int main()
{
  char arr[] = "abcdefghijk";
  my_memset(arr+1, 6, 3);
  printf("进过赋值后的结果->%s\n", arr);
  return 0;
}

在模拟实现memset函数中有一个小小的知识点就是:将数字转化成字符该如何转化,字符‘0’的ASCLL值为48,数字0的ASCLL值为0,所以将数字加上字符‘0’就可得到相应的字符

该函数实现的结果为:


四:memcmp函数

memcmp内存函数的实现原理:用于比较比较内存的前N个字节

字符串大小的比较是以ASCII 码表上的顺序来决定,次顺序亦为字符的值。memcmp()首先将s1 第一个字符值减去s2 第一个字符的值,若差为0 则再继续比较下个字符,若差值不为0 则将差值返回。

两个字符串内容完全一样,返回0;

若S1大于S2,则大于0,

反之则小于0;

memcmp的函数定义:从ptr1内存空间和ptr2内存空间依次向后进行比较size_t num个字节大小,且per1和ptr2进const修饰不可改变其内容。


模拟实现memcmp函数:

我们可以自己写一个my_mecmp函数来模拟实现memcmp函数的功能

首先定义函数void* my_memcmp(const void*ptr1,const void*ptr2,size_t num)

#include<stdio.h>
void* my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
  while (num--)
  {
    if (*(char*)ptr1 == *(char*)ptr2)
    {
      ptr1 = (char*)ptr1 + 1;
      ptr2 = (char*)ptr2 + 1;
    }
    else
    {
      return *(char*)ptr1 - *(char*)ptr2;
    }
  }
}
int main()
{
  char s1[] = "abcd456ef";
  char s2[] = "abef789nmn";
  int ret=my_memcmp(s1, s2, 5);
  printf("差值为->%d", ret);
 
  return 0;
}

其执行结果为:

执行结果:

my_memcmp(s1+7, s2,5):1 //字符串s1>字符串s2, 返回正值

my_memcmp(s1, s2,5):-1 // 字符串s1<字符串s2,返回负值

my_memcmp(s1, s2,2):0 //字符串s1=字符串s2, 返回0


如果觉得文章不错,期待你的一键三连哦,你个鼓励是我创作的动力之源,让我们一起加油,顶峰相见!!!

相关文章
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
182 3
|
7月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
370 15
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
483 6
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
269 0
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
326 0
|
7月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
2342 0
|
7月前
|
存储 缓存 NoSQL
内存管理基础:数据结构的存储方式
数据结构在内存中的存储方式主要包括连续存储、链式存储、索引存储和散列存储。连续存储如数组,数据元素按顺序连续存放,访问速度快但扩展性差;链式存储如链表,通过指针连接分散的节点,便于插入删除但访问效率低;索引存储通过索引表提高查找效率,常用于数据库系统;散列存储如哈希表,通过哈希函数实现快速存取,但需处理冲突。不同场景下应根据访问模式、数据规模和操作频率选择合适的存储结构,甚至结合多种方式以达到最优性能。掌握这些存储机制是构建高效程序和理解高级数据结构的基础。
777 0

热门文章

最新文章