深入探究 C 语言内存函数:memcpy、memmove、memset 和 memcmp ...

打印 上一主题 下一主题

主题 821|帖子 821|积分 2478

一,常见的内存函数

在 C 语言的编程天下里,对内存的高效操作至关重要。C 标准库为我们提供了一系列强大的内存操作函数,此中 memcpy、memmove、memset 和 memcmp 这四个函数是处理内存数据的得力助手。接下来,让我们深入相识它们的功能、使用方法以及适用场景。
1. memcpy:简单直接的内存复制

功能


memcpy 函数的主要功能是从源内存地址复制指定数量的字节到目标内存地址。它不关心内存中的内容是否为字符串,只是单纯地按字节举行复制。这使得它在复制数组、结构体等任意类型的数据时非常有用。
原型

   void *memcpy(void *dest, const void *src, size_t n);
  这里的参数解释如下:



  • dest:指向目标内存地区的指针,数据将被复制到这个位置。
  • src:指向源内存地区的指针,const 修饰表现该函数不会修改源内存中的内容。
  • n:要复制的字节数,这决定了复制操作的范围。
返回值


函数返回指向目标内存地区 dest 的指针,方便我们举行链式操作或后续的内存使用。
示例代码

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main() {
  4.     int src[] = {1, 2, 3, 4, 5};
  5.     int dest[5];
  6.     // 使用 memcpy 复制数组
  7.     memcpy(dest, src, sizeof(src));
  8.     // 输出复制后的数组
  9.     for (int i = 0; i < 5; i++) {
  10.         printf("%d ", dest[i]);
  11.     }
  12.     printf("\n");
  13.     return 0;
  14. }
复制代码
 
在这个示例中,我们使用 memcpy 将 src 数组的内容复制到 dest 数组中,通过 sizeof(src) 确保复制的字节数与源数组大小一致。
2. memmove:处理重叠内存的复制

功能

memmove 函数的功能和 memcpy 类似,也是从源内存地址复制指定数量的字节到目标内存地址。但它的优势在于能够处理源内存地区和目标内存地区有重叠的情况,会以一种安全的方式举行复制,制止数据覆盖问题。
原型

   void *memmove(void *dest, const void *src, size_t n);
  参数的含义和 memcpy 雷同。
返回值

同样返回指向目标内存地区 dest 的指针。
示例代码

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main() {
  4.     char str[] = "abcdefg";
  5.     // 有重叠的内存复制
  6.     memmove(str + 2, str, 3);
  7.     printf("%s\n", str);
  8.     return 0;
  9. }
复制代码
在这个例子中,我们将 str 字符串的前 3 个字符复制到从第 3 个字符开始的位置,由于存在内存重叠,使用 memmove 可以包管复制操作的精确性。
3. memset:内存地区的初始化利器

功能

memset 函数用于将指定内存地区的前 n 个字节设置为指定的值。这在初始化数组、结构体等内存地区时非常方便,好比将数组元素全部初始化为 0。
原型

   void *memset(void *s, int c, size_t n);
  参数分析如下:


  • s:指向要设置的内存地区的指针。
  • c:要设置的值,通常是一个字符或一个字节大小的整数,在内部会被转换为 unsigned char 类型。
  • n:要设置的字节数。
返回值

返回指向被设置的内存地区 s 的指针。
示例代码

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main() {
  4.     int arr[5];
  5.     // 将数组元素全部初始化为 0
  6.     memset(arr, 0, sizeof(arr));
  7.     // 输出初始化后的数组
  8.     for (int i = 0; i < 5; i++) {
  9.         printf("%d ", arr[i]);
  10.     }
  11.     printf("\n");
  12.     return 0;
  13. }
复制代码
在这个示例中,我们使用 memset 将 arr 数组的所有元素初始化为 0,通过 sizeof(arr) 确定要设置的字节数。
4. memcmp:内存内容的比较工具

功能

memcmp 函数用于比较两个内存地区的前 n 个字节。它按字节比较两个内存地区的内容,并返回一个表现大小关系的值,常用于比较数组、结构体等数据是否相等。
原型

   int memcmp(const void *s1, const void *s2, size_t n);
   
参数解释如下:


  • s1:指向第一个内存地区的指针。
  • s2:指向第二个内存地区的指针。
  • n:要比较的字节数。
返回值



  • 如果 s1 所指向的内存地区小于 s2 所指向的内存地区,返回一个负整数。
  • 如果两个内存地区相等,返回 0。
  • 如果 s1 所指向的内存地区大于 s2 所指向的内存地区,返回一个正整数。
示例代码

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main() {
  4.     int arr1[] = {1, 2, 3};
  5.     int arr2[] = {1, 2, 3};
  6.     // 比较两个数组
  7.     int result = memcmp(arr1, arr2, sizeof(arr1));
  8.     if (result == 0) {
  9.         printf("两个数组相等\n");
  10.     } else {
  11.         printf("两个数组不相等\n");
  12.     }
  13.     return 0;
  14. }
复制代码
总结


memcpy、memmove、memset 和 memcmp 这四个内存函数在 C 语言编程中各有其独特的用途。memcpy 适用于简单的非重叠内存复制,memmove 则是处理重叠内存复制的首选,memset 能高效地初始化内存地区,memcmp 可用于比较内存内容。熟练掌握这些函数,能让我们在处理内存数据时更加得心应手,编写出高效、稳固的 C 语言步伐。
 
二,模仿实现memcpy、memmove、memset 和 memcmp内存函数



1. 模仿 memcpy

代码实现

  1. #include <stdio.h>
  2. // 模拟 memcpy 函数
  3. void* my_memcpy(void* dest, const void* src, size_t n) {
  4.     char* d = (char*)dest;
  5.     const char* s = (const char*)src;
  6.     for (size_t i = 0; i < n; i++) {
  7.         d[i] = s[i];
  8.     }
  9.     return dest;
  10. }
  11. int main() {
  12.     int arr1[] = {1, 2, 3};
  13.     int arr2[3];
  14.     my_memcpy(arr2, arr1, sizeof(arr1));
  15.     for (int i = 0; i < 3; i++) {
  16.         printf("%d ", arr2[i]);
  17.     }
  18.     return 0;
  19. }
复制代码
具体解说



  • 功能:把源内存地区的数据复制到目标内存地区。
  • 参数处理:将 dest 和 src 逼迫转换为 char* 类型,因为 char 是 1 字节,方便按字节操作。
  • 复制过程:通过 for 循环,从源地址逐字节复制到目标地址,共复制 n 个字节。
  • 返回值:返回目标内存地区的指针。
2. 模仿 memmove

代码实现

  1. #include <stdio.h>
  2. // 模拟 memmove 函数
  3. void* my_memmove(void* dest, const void* src, size_t n) {
  4.     char* d = (char*)dest;
  5.     const char* s = (const char*)src;
  6.     if (d < s) {
  7.         // 目标地址在源地址前面,从前往后复制
  8.         for (size_t i = 0; i < n; i++) {
  9.             d[i] = s[i];
  10.         }
  11.     } else {
  12.         // 目标地址在源地址后面,从后往前复制,避免覆盖
  13.         for (size_t i = n; i > 0; i--) {
  14.             d[i - 1] = s[i - 1];
  15.         }
  16.     }
  17.     return dest;
  18. }
  19. int main() {
  20.     char str[] = "abcdefg";
  21.     my_memmove(str + 2, str, 3);
  22.     printf("%s\n", str);
  23.     return 0;
  24. }
复制代码
具体解说



  • 功能:和 memcpy 类似,但能处理内存重叠的情况。
  • 内存重叠判定:若 dest 地址小于 src 地址,从前今后复制;反之,从后往前复制。
  • 复制过程:根据判定结果,使用 for 循环举行逐字节复制。
  • 返回值:返回目标内存地区的指针。
3. 模仿 memset

代码实现

  1. #include <stdio.h>
  2. // 模拟 memset 函数
  3. void* my_memset(void* s, int c, size_t n) {
  4.     char* p = (char*)s;
  5.     for (size_t i = 0; i < n; i++) {
  6.         p[i] = (char)c;
  7.     }
  8.     return s;
  9. }
  10. int main() {
  11.     int arr[5];
  12.     my_memset(arr, 0, sizeof(arr));
  13.     for (int i = 0; i < 5; i++) {
  14.         printf("%d ", arr[i]);
  15.     }
  16.     return 0;
  17. }
复制代码
具体解说



  • 功能:将指定内存地区的前 n 个字节设置为指定的值。
  • 参数处理:将 s 逼迫转换为 char* 类型,方便按字节操作。
  • 设置过程:通过 for 循环,将每个字节设置为 c(转换为 char 类型)。
  • 返回值:返回被设置的内存地区的指针。
4. 模仿 memcmp

代码实现

  1. #include <stdio.h>
  2. // 模拟 memcmp 函数
  3. int my_memcmp(const void* s1, const void* s2, size_t n) {
  4.     const char* p1 = (const char*)s1;
  5.     const char* p2 = (const char*)s2;
  6.     for (size_t i = 0; i < n; i++) {
  7.         if (p1[i] != p2[i]) {
  8.             return p1[i] - p2[i];
  9.         }
  10.     }
  11.     return 0;
  12. }
  13. int main() {
  14.     int arr1[] = {1, 2, 3};
  15.     int arr2[] = {1, 2, 3};
  16.     int result = my_memcmp(arr1, arr2, sizeof(arr1));
  17.     printf("%d\n", result);
  18.     return 0;
  19. }
复制代码
具体解说



  • 功能:比较两个内存地区的前 n 个字节。
  • 参数处理:将 s1 和 s2 逼迫转换为 char* 类型,方便按字节比较。
  • 比较过程:通过 for 循环逐字节比较,若发现差别字节,返回它们的差值。
  • 返回值:若都雷同返回 0;若 s1 大于 s2 返回正数;若 s1 小于 s2 返回负数。
                                    以上就是具体解说了模仿实现内存函数的例子

希望这篇文章能帮助你更好地理解和使用这些重要的 C 语言内存函数!如果你在使用过程中遇到任何问题,欢迎在评论区留言交流。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连全瓷种植牙齿制作中心

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表