• C语言零基础教程(memset,memcpy函数,memmove函数)



    前言

    本篇文章来讲解一下memset和memcpy函数,这两个函数在C语言中也是比较重要的,这里我们就来学习一下这两个函数的使用方法吧。

    一、memset函数

    memset 函数是一个C标准库中的函数,用于将一块内存区域的每个字节设置为指定的值。

    memset 的定义如下:

    void *memset(void *ptr, int value, size_t num);
    
    • 1

    函数的参数包括 ptr,表示要设置的内存区域的起始地址;value,表示要设置的值,通常以整数表示,但在传给 memset 时会自动转换为 unsigned char 类型;num,表示要设置的字节数。

    memset 函数的工作原理是将指定值 value 拷贝到指定内存区域 ptr 所指向的每个字节中,重复拷贝 num 次。

    常见的用法是将内存区域初始化为特定值,例如将整个数组清零:

    int arr[10];
    memset(arr, 0, sizeof(arr));
    
    • 1
    • 2

    上述代码将数组 arr 的所有元素设置为零。这是非常高效的一种方式,特别是对于大型数组或者结构体,因为它直接操作内存,而不是逐个元素赋值。

    需要注意的是,memset 函数只能设置每个字节的值,因此对于非 char 型的数组,设置的值可能会被截断或产生不可预测的结果。针对非字符类型的数组或结构体,应该使用其他方法来进行赋值。

    此外,还需要谨慎使用 memset,因为它没有边界检查,容易导致越界操作或者非法访问内存。

    易错点:

    当使用 memset 函数给不同类型的数组置为某个值时,确实需要注意不同类型的字节大小和表示范围,以避免出现问题。以下是一个示例:

    #include 
    #include 
    
    int main() {
      int intArray[5];
      char charArray[5];
    
      // 设置 int 类型数组为 1
      memset(intArray, 1, sizeof(intArray));
    
      // 设置 char 类型数组为 1
      memset(charArray, 1, sizeof(charArray));
    
      printf("intArray:\n");
      for (int i = 0; i < 5; i++) {
        printf("%d ", intArray[i]);
      }
    
      printf("\n\ncharArray:\n");
      for (int i = 0; i < 5; i++) {
        printf("%d ", charArray[i]);
      }
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    运行上述代码,输出如下:

    intArray:
    16843009 16843009 16843009 16843009 16843009
    
    charArray:
    1 1 1 1 1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    可以看到,memset 函数对 int 类型数组的每个字节都设置为 1,并没有按预期将整个 int 类型的元素设置为 1。这是因为 memset 函数按字节拷贝,将 1(int 类型转换为 unsigned char 类型)复制到了每个字节,并没有设置整个 int 类型元素的值。

    相比之下,对 char 类型数组使用 memset 函数,每个字节都被设置为 1,包括 ASCII 值为 1 的字符。

    因此,在使用 memset 函数时,应注意被设置的值要与数组元素类型相匹配,以避免产生意料之外的结果。如果想将整个 int 类型数组设置为某个值,可以使用循环逐个赋值的方式来确保正确设置。

    二、memcpy函数

    memcpy 函数是 C 标准库中的一个函数,用于在内存之间进行字节级别的数据拷贝。memcpy 可以将源内存区域的内容复制到目标内存区域,并返回指向目标内存区域的指针。

    memcpy 的定义如下:

    void *memcpy(void *dest, const void *src, size_t n);
    
    • 1

    函数的参数包括 dest,表示目标内存区域的起始地址;src,表示源内存区域的起始地址;n,表示要复制的字节数。

    memcpy 函数会将源内存区域中的 n 个字节的数据复制到目标内存区域,可能包含原先的内容。函数不会检查边界,因此保证源和目标内存区域的大小至少为 n 是非常重要的。

    以下是一个示例,展示 memcpy 的用法:

    #include 
    #include 
    
    int main() {
        char src[] = "Hello, world!";
        char dest[20];
    
        memcpy(dest, src, strlen(src) + 1);
    
        printf("Copied string: %s\n", dest);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上述代码将源字符串 src 复制到目标字符数组 dest 中。memcpy 函数使用了 strlen(src) + 1 作为要复制的字节数,确保整个字符串被复制到目标数组中,包括字符串的结尾符 ‘\0’。

    在运行代码后,输出如下:

    Copied string: Hello, world!
    
    • 1

    可以看到,源字符串 src 成功地复制到了目标字符数组 dest 中。

    需要注意的是,memcpy 函数在进行内存拷贝时是按字节级别操作的,不关心内存中保存的是什么类型的数据。这也意味着在使用 memcpy 时,应确保源和目标内存区域之间没有重叠,以免产生意想不到的结果。如果源和目标内存区域有重叠,可以使用 memmove 函数来避免数据被破坏。

    三、memmove函数

    memmove 函数是一个 C 标准库中的函数,用于在内存之间进行字节级别的数据拷贝。与 memcpy 函数不同的是,memmove 函数可以处理可能发生重叠的内存区域的拷贝。

    memmove 的定义如下:

    void *memmove(void *dest, const void *src, size_t n);
    
    • 1

    函数的参数包括 dest,表示目标内存区域的起始地址;src,表示源内存区域的起始地址;n,表示要复制的字节数。

    memmove 函数将会将源内存区域中的 n 个字节的数据复制到目标内存区域中,即使源和目标内存区域有部分或完全重叠。函数会自动处理重叠情况,以确保数据被正确复制。

    以下是一个示例,展示 memmove 的用法:

    #include 
    #include 
    
    int main() {
      char str[] = "Hello, world!";
      memmove(str + 7, str, strlen(str) + 1);
    
      printf("Moved string: %s\n", str);
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    上述代码将字符串 str 移动了 7 个位置,即将字符串的前部分移动到后部分。在这个例子中,memmove 函数被用来处理源和目标内存区域可能重叠的情况。

    运行代码后,输出如下:

    Moved string: world! Hello,
    
    • 1

    可以看到,源字符串 str 成功地移动了 7 个位置,并且重叠部分的数据也被正确处理。

    需要注意的是,相比于 memcpy 函数,memmove 函数的实现可能会更加复杂和耗时,因为需要处理内存区域的重叠情况。因此,在没有重叠的情况下,推荐使用 memcpy 函数来进行拷贝操作,因为它的实现更简单且通常更高效。只有当存在内存区域重叠的情况时,才需要使用 memmove 函数

    总结

    本篇文章就讲解到这里,大家看完后可以进行实验验证。

  • 相关阅读:
    抖音众多接口展示
    文件操作与IO
    【超强图解Docker常见命令与实战】
    「MySQL-02」数据库的操纵、备份、还原和编码规则
    初识Canal以及使用Docker安装配置
    现有版本的QT中可用数据库插件驱动查看
    第55节—— redux-toolkit中的createReducer——了解
    【Python模块】图形化编程模块-turtle
    应该选择网络安全还是程序员?
    狂神说多线程学习笔记
  • 原文地址:https://blog.csdn.net/m0_49476241/article/details/131997972