C语言之内存函数

内存函数:通常指的是在编程中用于处理内存操作的函数,这些函数可以用来分配、释放、复制、比较等内存相关的操作。在C语言中,这些内存函数 memcpy()memmove()memset()memcmp() 都需要引用头文件

1.memcpy函数

memcpy() 函数的原型如下:

void *memcpy(void *dest, const void *src, size_t n);
  • dest:目标内存地址,即要将数据复制到的位置。
  • src:源内存地址,即要复制数据的起始位置。
  • n:要复制的字节数。

memcpy() 函数会从源内存地址 src 复制 n 个字节的数据到目标内存地址 dest,并返回目标内存地址 dest

#include 

void *memcpy_custom(void *dest, const void *src, size_t n) {
    // 将源地址src的内容复制到目标地址dest
    // 注意:此处假设目标地址和源地址不会重叠

    // 将void指针转换为char指针,方便按字节进行操作
    char *p_dest = (char *)dest;
    const char *p_src = (const char *)src;

    // 逐字节复制数据
    for (size_t i = 0; i < n; i++) {
        p_dest[i] = p_src[i];
    }

    return dest;
}

int main() {
    char src[] = "Hello, world!";
    char dest[20];

    // 调用自定义的memcpy函数
    memcpy_custom(dest, src, sizeof(src));

    // 输出复制后的字符串
    printf("Copied string: %s\n", dest);

    return 0;
}

C语言之内存函数_第1张图片

假设存在两片这样的空间由两个指针“dest”和“src”维护,解引用赋值过去相当于copy过去一个字节

然后“dest++”和“src++”就指向下一内存单元,重复之前的操作直至来到最后一个内存单元,也就是第n个,至此操作完成返回目标内存的起始地址

C语言之内存函数_第2张图片

2.memmove函数

memmove() 类似于 memcpy(),但更安全,可以处理内存块重叠的情况,内存块重叠情况就是当我们

src所指向的内存块和dest所指向的内存块发生重叠的情况,如下图

C语言之内存函数_第3张图片

当我们如果想进行像memcpy() 那样操作时就会篡改src所指向的内存块从而达不到copy效果当我们走到最后变成这样

C语言之内存函数_第4张图片

而memmove就是避免这种情况而造就的,实现原理也很简单当src的起始位置大于dest的起始位置,我们就从后往前复制,当src的起始位置小于dest的起始位置,就从前向后复制,至此实现正确复制,这样做的原理就是先把重合部分拿出来复制,这样就可以避免篡改源内存块

memmove实现

#include 

void *memmove_custom(void *dest, const void *src, size_t n) {
    // 将源地址src的内容复制到目标地址dest
    // 处理重叠情况时,从后往前复制

    // 将void指针转换为char指针,方便按字节进行操作
    char *p_dest = (char *)dest;
    const char *p_src = (const char *)src;

    // 处理重叠情况时,从后往前复制
    if (p_dest > p_src && p_dest < p_src + n) {
        for (size_t i = n - 1; i < n; i--) {
            p_dest[i] = p_src[i];
        }
    } else {
        // 普通情况下,从前往后复制
        for (size_t i = 0; i < n; i++) {
            p_dest[i] = p_src[i];
        }
    }

    return dest;
}

int main() {
    char src[] = "Hello, world!";
    char dest[20];

    // 调用自定义的memmove函数
    memmove_custom(dest, src, sizeof(src));

    // 输出复制后的字符串
    printf("Copied string: %s\n", dest);

    return 0;
}

3.memcmp函数

memcmp() 是C语言中用于比较内存区域的函数,类似于strncmp函数但是memcmp更加通用,因为它比较的是内存中的值而不只限于字符串

其原型如下:

int memcmp(const void *s1, const void *s2, size_t n);
  • s1:指向要比较的第一个内存区域的指针。
  • s2:指向要比较的第二个内存区域的指针。
  • n:要比较的字节数。

memcmp() 函数会比较 s1s2 所指向的内存区域的前 n 个字节,并返回一个整数来表示比较结果。

  • 如果第一个区域的字节值小于第二个区域的字节值,则返回负值。
  • 如果第一个区域的字节值大于第二个区域的字节值,则返回正值。
  • 如果两个区域的字节值都相等,则返回0。

实现:

#include 

int memcmp_custom(const void *s1, const void *s2, size_t n) {
    // 将void指针转换为char指针,方便按字节进行比较
    const unsigned char *p1 = (const unsigned char *)s1;
    const unsigned char *p2 = (const unsigned char *)s2;

    // 逐字节比较数据
    for (size_t i = 0; i < n; i++) {
        if (p1[i] != p2[i]) {
            // 如果有不相等的字节,则返回它们的差值
            return (p1[i] > p2[i]) ? 1 : -1;
        }
    }

    // 如果所有字节都相等,则返回0
    return 0;
}

int main() {
    char s1[] = "Hello";
    char s2[] = "Hella";

    // 调用自定义的memcmp函数
    int result = memcmp_custom(s1, s2, 5);

    if (result == 0) {
        printf("s1 和 s2 相等\n");
    } else if (result > 0) {
        printf("s1 大于 s2\n");
    } else {
        printf("s1 小于 s2\n");
    }

    return 0;
}

4.memset函数

memset() 是C语言中用于设置内存块的函数,其原型如下

void *memset(void *s, int c, size_t n);
  • s:指向要设置的内存块的指针。
  • c:要设置的值,以整数形式给出,通常是一个字节的值。
  • n:要设置的字节数。

memset() 函数将指定的值 c 复制到 s 所指向的内存块的前 n 个字节中。通常情况下,c 是一个无符号字符或整数(0~255),会被转换成无符号字符并复制到内存块中。

memset() 主要用于初始化内存块,可以用来快速将一段内存区域填充为指定的值。它经常用于数组初始化、清除内存等操作。

实现:

#include 

void *memset_custom(void *s, int c, size_t n) {
    // 将指定的值c复制到s所指向的内存块的前n个字节中

    // 将void指针转换为char指针,方便按字节进行操作
    unsigned char *p = (unsigned char *)s;

    // 将指定的值复制到内存块中
    for (size_t i = 0; i < n; i++) {
        p[i] = (unsigned char)c;
    }

    return s;
}

int main() {
    char arr[10];

    // 调用自定义的memset函数,将数组arr的前5个字节设置为'a'的ASCII码值
    memset_custom(arr, 'a', 5);

    // 输出设置后的数组内容
    for (int i = 0; i < 10; i++) {
        printf("%c ", arr[i]);
    }
    printf("\n");

    return 0;
}

你可能感兴趣的:(c语言,开发语言)