C语言 内存函数

目录

1.memcpy函数

2.memmove函数

3.memset函数

4.memcmp函数


C语言中内存函数主要用于对内存空间进行操作,可分为内存拷贝、内存设置、内存比较和动态内

存管理等几类,以下是详细介绍:

1.memcpy函数

1.1函数定义

memcpy  是C语言标准库函数,用于在内存中复制数据块,在 <string.h>  头文件中声明 。以下是

详细介绍:

1.2函数原型

 void* memcpy(void* destination, const void* source, size_t num); 

-  destination  :指向用于存储复制内容的目标内存块的指针,类型为  void*  ,这意味着它可以接

受任意类型的指针。

-  source  :指向要复制的数据源内存块的指针,类型为  const void*  ,表明该指针指向的内容不

会在函数中被修改。

-  num  :要复制的字节数,类型为  size_t  ,它是一个无符号整数类型,通常用于表示对象的大

小。

1.3函数功能

从 source  所指向的内存地址起始位置开始,将 num  个字节的数据直接复制到 destination  所

指向的内存地址起始位置中 。复制过程是逐字节进行,不关心被复制数据的具体类型,可用于字

符数组、整型数组、结构体、类等任意数据类型。例如:

1.4代码演示:

#include <stdio.h>
#include <string.h>
int main() {
    char src[10] = "hello";
    char dst[10] = {0};
    memcpy(dst, src, strlen(src) + 1); // 复制字符串,包括'\0'
    printf("%s\n", dst); 
    int arr1[3] = {1, 2, 3};
    int arr2[3];
    memcpy(arr2, arr1, sizeof(arr1)); // 复制整型数组
    for (int i = 0; i < 3; i++) {
        printf("%d ", arr2[i]);
    }
    return 0;
}

1.5注意事项

- 内存空间要求:目标内存块  destination  必须提前分配足够大空间,以容纳  num  个字节数据,

否则会导致缓冲区溢出,引发未定义行为 。

- 内存重叠问题:源内存块  source  和目标内存块  destination  所指区域不能重叠。若发生重叠,

复制结果未定义,这种情况下应使用  memmove  函数,它能安全处理重叠内存区域的复制。

- 数据类型无关性:该函数不检查源数据中是否有终止符(如字符串的  '\0'  ) ,始终精确复制指

定的  num  个字节。这在复制包含  '\0'  数据(如二进制数据)时很有用,但处理字符串时要注意

手动添加或处理结束符 。

2.memmove函数

2.1函数定义

memmove  是 C 语言标准库函数,用于安全复制内存块,声明于  <string.h>  头文件。以下是详细

说明:

2.2函数原型

void* memmove(void* destination, const void* source, size_t num);

-  destination :目标内存块指针( void* ,可接受任意类型)。

-  source :源内存块指针( const void* ,不可修改源数据)。

-  num :要复制的字节数( size_t  无符号整数)。

2.3函数功能

从  source  指向的内存区域复制  num  个字节到  destination  指向的区域。

与  memcpy  的关键区别:
 
- 允许内存重叠:即使  source  和  destination  指向的区域有重叠, memmove  也能正确复制数

据。

- 例如:复制数组中某段重叠区域时, memmove  会先将源数据临时缓存,避免覆盖未复制的内

容。

2.4代码演示:

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

int main() {
    // 场景:内存重叠的数组复制(向前覆盖)
    int arr[] = {1, 2, 3, 4, 5};
    size_t len = sizeof(arr) / sizeof(arr[0]);
    
    // 将前 3 个元素复制到从第 2 个元素开始的位置(重叠区域)
    memmove(arr + 1, arr, 3 * sizeof(int)); // 结果:[1, 1, 2, 4, 5]
    
    for (int i = 0; i < len; i++) {
        printf("%d ", arr[i]); // 输出:1 1 2 4 5
    }
    return 0;
}

2.5注意事项

1. 内存分配:目标区域需提前分配足够空间,避免缓冲区溢出。

2. 安全复制:若明确内存无重叠, memcpy  可能更高效(因无需处理缓存逻辑);若可能重叠,

必须用  memmove 。

3. 数据类型无关:和  memcpy  一样,按字节复制,适用于任意数据类型(如结构体、二进制数

据)。

2.6与memcpy的区别

-  memmove :安全处理重叠内存的复制,适用于不确定内存是否重叠的场景。

-  memcpy :高效处理非重叠内存的复制,但重叠时结果未定义。

3.memset函数

3.1函数定义

memset  是 C 语言标准库函数,用于初始化内存块,声明于 <string.h>  头文件。以下是详细说

明:

3.2函数原型

void* memset(void* s, int c, size_t n);

-  s :目标内存块指针( void* ,可接受任意类型)。

-  c :要设置的值(会被转换为  unsigned char  类型)。

-  n :要初始化的字节数( size_t  无符号整数)。

3.3函数功能


将  s  指向的内存区域的前  n  个字节逐字节设置为  c  的值(实际操作时, c  会被强制转换为

 unsigned char  类型)。

适用场景:

 - 初始化数组、结构体为特定值(如全零、全  \0 )。

- 清空内存块(如用  0  填充)。

3.4代码演示:

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

int main() {
    // 初始化字符数组为全 'a'
    char str[10];
    memset(str, 'a', sizeof(str)); // str 内容:"aaaaaaaaaa"
    printf("%s\n", str); // 输出:aaaaaaaaaa

    // 初始化整型数组为全 0(注意:仅当 0 的二进制字节模式全为 0 时有效)
    int arr[5];
    memset(arr, 0, sizeof(arr)); // 所有元素被设为 0
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]); // 输出:0 0 0 0 0
    }

    // 结构体初始化(设为全零)
    struct Data { int x; float y; };
    struct Data data;
    memset(&data, 0, sizeof(data)); // 等价于 data.x=0; data.y=0.0f;
    return 0;
}

z3.5注意事项

1. 按字节赋值:

-  memset  是逐字节操作,因此对多字节数据类型(如  int 、 float )赋值时需谨慎。

- 例: memset(arr, 1, sizeof(arr))  会将每个字节设为  1 ,但整型  1  的二进制是  0x00000001 ,

逐字节填充后可能变为  0x01010101 (取决于字节序),结果并非预期的  1 。

- 正确做法:多字节类型需逐个元素初始化,或用  0  填充(因  0  的字节模式全为  0 )。

2. 内存越界:

- 目标指针  s  必须指向有效内存,且  n  不能超过该内存块的大小,否则会引发未定义行为(如程

序崩溃)。

3. 与字符串的区别:

- 处理字符串时, memset  不会自动添加  '\0'  终止符,需手动控制长度(如复制字符串时需包含

 '\0' )。

4.memcmp函数

4.1函数定义

memcmp  是 C 语言标准库函数,用于比较两个内存块的二进制数据,声明于 <string.h>  头文

件。以下是详细说明:

4.2函数原型

int memcmp(const void* s1, const void* s2, size_t n);

-  s1 / s2 :指向待比较的两个内存块的指针( const void* ,不可修改数据)。

-  n :要比较的字节数( size_t  无符号整数)。

4.3函数功能

从  s1  和  s2  指向的内存区域的前  n  个字节开始,按字节顺序逐字节比较二进制值,直到发现不

相等的字节或比较完  n  个字节为止。
 
返回值
 
-  < 0 : s1  中第一个不相等的字节的值 小于  s2  对应字节的值。
-  = 0 :两个内存块的前  n  个字节完全相等。
-  > 0 : s1  中第一个不相等的字节的值 大于  s2  对应字节的值。

4.4代码演示:

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

int main() {
    // 比较字符数组(按 ASCII 码值)
    char str1[] = "hello";
    char str2[] = "helloworld";
    int result = memcmp(str1, str2, 5); // 前 5 字节相等,返回 0
    printf("memcmp result: %d\n", result); // 输出:0

    // 比较整型数组(按二进制字节)
    int arr1[] = {0x1234, 0x5678}; // 假设小端序,内存中为 [0x34, 0x12, 0x78, 0x56]
    int arr2[] = {0x1234, 0x5670}; // 内存中为 [0x34, 0x12, 0x70, 0x56]
    result = memcmp(arr1, arr2, sizeof(int) * 2); // 前 4 字节相等,第 5 字节(0x78 vs 0x70)不相等
    printf("memcmp result: %d\n", result); // 输出:正数(因 0x78 > 0x70)

    // 比较结构体(按内存布局)
    struct Data { char a; int b; } data1 = {'a', 100}, data2 = {'a', 200};
    result = memcmp(&data1, &data2, sizeof(struct Data)); // 前 1 字节相等,第 2-5 字节(100 vs 200 的二进制)不同
    printf("memcmp result: %d\n", result); // 输出:负数(因 100 < 200 的二进制值)
    return 0;
}

4.5注意事项

1. 二进制比较:

- 与  strcmp  不同, memcmp  会严格比较每个字节的二进制值,包括  \0  在内的所有字节

( strcmp  遇到  \0  会提前终止)。

- 例: memcmp("abc", "ab\0c", 3)  返回  0 (前 3 字节均为  'a' 、 'b' 、 '\0' )。

2. 长度控制:

- 若  n  超过实际内存块大小,会访问越界内存,导致未定义行为。

3. 数据类型无关:

- 可用于比较任意类型的数据(如数组、结构体、二进制文件数据),只需确保比较长度  n  正

确。
 

以上便是与内存处理有关的四个函数,希望大家能够理解,感谢大家的观看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值