1.内存处理函数的用处

2.内存处理函数的模型和应用场景

- memcpy

在 C 语言中,memcpy 是核心内存操作函数,用于从源地址向目标地址拷贝指定字节数的内存数据,且不做数据类型解析(按字节逐位拷贝),是高效且通用的内存复制工具,定义在 <string.h> 头文件中。

形式(参数含义)

void *memcpy(void *dest, const void *src, size_t n);
参数 含义
dest 目标内存地址(拷贝后数据存放的位置),需保证该区域有足够空间容纳 n 字节
src 源内存地址(待拷贝数据的起始位置),const 表示源数据只读,防止被修改
n 要拷贝的字节数,size_t 是无符号整型
  • 使用样例:1.拷贝基本类型数组
#include <stdio.h>
#include <string.h>

int main() {
    int src[] = {1, 2, 3, 4, 5};
    int dest[5];
    // 拷贝整个int数组:5个int元素 × 4字节/int = 20字节
    memcpy(dest, src, sizeof(src));
    
    for (int i = 0; i < 5; i++) {
        printf("%d ", dest[i]); // 输出:1 2 3 4 5
    }
    return 0;
}

2.拷贝部分数据(指定字节数)

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Hello, memcpy!";
    char dest[20] = {0};
    // 仅拷贝前5个字节
    memcpy(dest, src, 5);
    
    printf("dest: %s\n", dest); // 输出:dest: Hello
    return 0;
}
  • 在使用memcpy函数的时候我们要注意:
  1. 给定的参数要对应类型一致
  2. 注意内存重叠问题当我们的dest和src的位置处于重叠状态,memcpy是不可以处理的。
  3. 返回值为 dest 指针,可直接用于后续操作。
  4. 必须保证 dest 有至少 n 字节的可用空间,否则会导致内存越界。

- memmove

在 C 语言中,memmove专门解决内存重叠场景的内存拷贝函数,与 memcpy 核心功能一致(字节级拷贝),但能安全处理源地址(src)和目标地址(dest)内存区域重叠的情况,定义在 <string.h> 头文件中。

使用(参数含义)

void *memmove(void *dest, const void *src, size_t n);
参数 含义
dest 目标内存地址,需保证有至少 n 字节可用空间
src 源内存地址(待拷贝数据的起始位置),const 表示源数据只读,防止被修改
n 要拷贝的字节数,size_t 是无符号整型
  • 使用样例:1.处理内存重叠
#include <stdio.h>
#include <string.h>

int main() {
    char arr[] = "1234567890";
    // 场景:dest = src + 2(内存重叠)
    // 用 memcpy 会出错,用 memmove 正确
    memmove(arr + 2, arr, 5); 
    
    printf("arr: %s\n", arr); // 输出:arr: 1212345890
    return 0;
}
  • 使用样例:2.普通场景(无重叠,等价于 memcpy)
#include <stdio.h>
#include <string.h>

typedef struct {
    int id;
    char name[10];
} Student;

int main() {
    Student s1 = {101, "LiSi"};
    Student s2;
    // 无重叠,memmove 等价于 memcpy
    memmove(&s2, &s1, sizeof(Student));
    
    printf("id: %d, name: %s\n", s2.id, s2.name); // 输出:id: 101, name: LiSi
    return 0;
}

- 在使用memmove函数的时候我们要注意:

  1. 必须保证 dest 有至少 n 字节的可用空间,否则会内存越界。
  2. memmove 是标准库函数,所有 C 编译器均支持,可放心替代 memcpy 用于所有拷贝场景。
  3. 处理我们的重叠问题专用
  4. 返回值为: dest 指针

- memset

在 C 语言中,memset 是用于按字节批量初始化内存的核心函数,能快速将指定内存区域的每一个字节设置为相同的数值,定义在 <string.h> 头文件中。它是初始化内存(如清零、填充固定值)的高频工具,效率远高于手动循环赋值。

形式(参数含义)

void *memset(void *s, int c, size_t n);
参数 含义
s 待初始化的内存起始地址(如数组、结构体指针)
c 要设置的字节值(实际只取低 8 位,范围 0~255,超出会截断)
n 初始化的字节数,无符号整型
  • 使用样例:1.内存清零
#include <stdio.h>
#include <string.h>

int main() {
    // 1. 初始化字符数组
    char str[20];
    memset(str, 0, sizeof(str)); // 全部字节置0
    strcpy(str, "memset test");
    printf("str: %s\n", str); // 输出:str: memset test

    // 2. 初始化整型数组
    int arr[5] = {1, 2, 3, 4, 5};
    memset(arr, 0, sizeof(arr)); // 每个字节置0 → 整个int数组为0
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]); // 输出:0 0 0 0 0
    }
    return 0;
}
  • 使用样例:2.初始化结构体
#include <stdio.h>
#include <string.h>

typedef struct {
    int id;
    char name[20];
    float score;
} Student;

int main() {
    Student s = {101, "ZhangSan", 95.5};
    memset(&s, 0, sizeof(Student)); // 结构体所有字节置0
    
    printf("id: %d, name: %s, score: %.1f\n", s.id, s.name, s.score);
    // 输出:id: 0, name: , score: 0.0
    return 0;
}

- 在使用memset函数的时候我们要注意:

  1. 按字节赋值仅对单字节类型(char)能直接设置任意值(如 ‘a’、10),对多字节类型(int、float、long),仅能安全设置 0(所有字节为 0 时,数值就是 0);
  2. 必须保证 n 不超过 s 指向的内存可用范围,否则会内存越界。
  3. 返回值为: s 指针

- memcmp

在 C 语言中,memcmp 是用于按字节逐位比较两块内存区域的核心函数,可比较任意类型的内存数据(字符、整型、结构体等),返回值反映两块内存的****大小关系,定义在 <string.h> 头文件中。

形式(参数含义)

int memcmp(const void *s1, const void *s2, size_t n);
参数 含义
s1 第一块待比较的内存起始地址(只读,不修改)
s2 第二块待比较的内存起始地址(只读,不修改)
n 比较的字节数,无符号整型

- 返回值–返回值为 int,反映 s1 和 s2 前 n 字节的比较结果:

返回值 含义
< 0 s1 中第一个不同字节的二进制值 < s2 对应字节
= 0 s1 和 s2 前 n 字节完全相同
> 0 s1 中第一个不同字节的二进制值 > s2 对应字节

关键:比较仅在第一个不同字节处终止,后续字节不再对比;若前 n 字节均相同,返回 0。

  • 使用样例:1.比较字符数组
#include <stdio.h>
#include <string.h>

int main() {
    char s1[] = "Hello";
    char s2[] = "World";
    char s3[] = "Hello";
    
    // 比较前5个字节
    int res1 = memcmp(s1, s2, 5);
    int res2 = memcmp(s1, s3, 5);
    
    printf("s1 vs s2: %d\n", res1); // 输出:-1('H'(0x48) < 'W'(0x57))
    printf("s1 vs s3: %d\n", res2); // 输出:0(完全相同)
    return 0;
}
  • 使用样例:2.比较整型数组
#include <stdio.h>
#include <string.h>

int main() {
    int arr1[] = {1, 2, 3, 4};
    int arr2[] = {1, 2, 4, 5};
    int arr3[] = {1, 2, 3, 4};
    
    // 比较前3个int元素(3×4=12字节)
    int res = memcmp(arr1, arr2, 12);
    printf("arr1 vs arr2: %d\n", res); // 输出:-1(第三个元素3(0x03) < 4(0x04))
    
    res = memcmp(arr1, arr3, sizeof(arr1));
    printf("arr1 vs arr3: %d\n", res); // 输出:0(完全相同)
    return 0;
}

- 在使用memcmp函数的时候我们要注意:

  1. 字节比较的规则:
    –‘a’(0x61) > ‘A’(0x41);
    –数值 1< 数值 255;
    --负数的补码形式会按二进制值对比(如 int -1 的补码是 0xFFFFFFFF,比 int 1 大)。
  2. memcmp 不识别 \0,仅按指定 n 字节比较;而 strcmp 会遇 \0 终止,且仅比较字符串。
  3. 返回值是int类型的我们要记好不要区分不开

3.比较内存函数的区别

memcpy vs memmove vs memset vs memcmp(核心区别)

特性 memcpy memmove memset memcmp
核心功能 字节级内存拷贝 字节级内存拷贝(安全处理重叠) 字节级内存初始化(置固定值) 字节级内存比较
关键参数 dest, src, n(字节数) dest, src, n(字节数) s, c(字节值), n(字节数) s1, s2, n(字节数)
内存重叠 不处理(结果未定义) 安全处理(正向 / 反向拷贝) 无重叠概念 无重叠概念
返回值 指向 dest 的指针 指向 dest 的指针 指向 s 的指针 int(<0/0/>0)
性能 最高(无额外判断) 略低(多地址判断) 极高(批量字节赋值) 逐字节对比(找到差异即终止)
核心限制 仅无重叠场景可用 无明显限制 仅单字节类型可任意置值 结构体填充字节可能导致误判

总结😗

  1. memcpy:无重叠的高效内存拷贝
    核心场景:明确 目标内存无重叠时,快速拷贝任意类型数据。
  2. memmove:任意场景的安全内存拷贝
    核心场景:目标内存可能重叠,或不确定是否重叠时的拷贝
  3. memset:批量内存初始化(尤其清零)
    核心场景:快速初始化内存,优先用于 “清零”,其次是单字节类型填充。
  4. memcmp:字节级内存对比
    核心场景:对比任意类型内存的二进制内容,判断是否一致或大小关系
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐