C语言从入门到进阶——第18讲:内存函数

文章目录

  • [1. memcpy](#1. memcpy)
  • [2. memmove](#2. memmove)
  • [3. memset](#3. memset)
  • [4. memcmp](#4. memcmp)

1. memcpy

函数原型

c 复制代码
void * memcpy ( void * destination, const void * source, size_t num );

功能

  • memcpy是完成内存块拷贝的,不关注内存中存放的数据是啥
  • 函数memcpysource的位置开始向后复制num个字节的数据到destination 指向的内存位置。
  • 如果sourcedestination有任何的重叠,复制的结果都是未定义的。
    • 内存重叠的情况使用memmove就行
  • memcpy 的使用需要包含<string.h>

参数

  • destination:指针,指向目标空间,拷贝的数据存放在这里
  • source:指针,指向源空间,要拷贝的数据从这里来
  • num:要拷贝的数据占据的字节数

返回值

拷贝完成后,返回目标空间的起始地址

代码演示

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    int arr2[10] = { 0 };
    memcpy(arr2, arr1, 20);
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", arr2[i]);
    }
    return 0;
}

模拟实现

c 复制代码
void * memcpy ( void * dst, const void * src, size_t count)
{
    void * ret = dst;
    assert(dst);
    assert(src);

    // copy from lower addresses to higher addresses
    while (count--) {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
    }
    return(ret);
}

2. memmove

函数原型

c 复制代码
void * memmove ( void * destination, const void * source, size_t num );

功能

  • memmove函数也是完成内存块拷贝的
  • memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • memmove的使用需要包含<string.h>

参数

  • destination:指针,指向目标空间,拷贝的数据存放在这里
  • source:指针,指向源空间,要拷贝的数据从这里来
  • num:要拷贝的数据占据的字节数

返回值

拷贝完成后,返回目标空间的起始地址

代码演示

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    memmove(arr1 + 2, arr1, 20);
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", arr1[i]);
    }
    return 0;
}

输出的结果

复制代码
1 1 2 3 4 5 6 7 8 9 10

模拟实现

c 复制代码
void * memmove ( void * dst, const void * src, size_t count)
{
    void * ret = dst;
    if (dst <= src || (char *)dst >= ((char *)src + count)) {
        // Non-Overlapping Buffers
        // copy from lower addresses to higher addresses
        while (count--) {
            *(char *)dst = *(char *)src;
            dst = (char *)dst + 1;
            src = (char *)src + 1;
        }
    }
    else {
        // Overlapping Buffers
        // copy from higher addresses to lower addresses
        dst = (char *)dst + count - 1;
        src = (char *)src + count - 1;

        while (count--) {
            *(char *)dst = *(char *)src;
            dst = (char *)dst - 1;
            src = (char *)src - 1;
        }
    }
    return(ret);
}

3. memset

函数原型

c 复制代码
void * memset ( void * ptr, int value, size_t num );

功能

  • memset函数是用来设置内存块的内容的,将内存中指定长度的空间设置为特定的内容。
  • memset的使用需要包含<string.h>

参数

  • ptr:指针,指向要设置的内存空间,也就是存放了要设置的内存空间的起始地址。
  • value:要设置的值,函数将会把value值转换成unsigned char的数据进行设置的。也就是以字节为单位来设置内存块的。
  • num:要设置的内存长度,单位是字节。

返回值

返回的是要设置的内存空间的起始地址。

代码演示

c 复制代码
#include <stdio.h>
#include <string.h>
int main () {
    char str[] = "hello world";
    memset (str,'x',6);
    printf(str);
    return 0;
}

输出的结果

复制代码
xxxxxxworld

总结

当有一块内存空间需要设置内容的时候,就可以使用memset函数,值得注意的是memset函数对内存单元的设置是以字节为单位的。

4. memcmp

函数原型

c 复制代码
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

功能

比较指定的两块内存块的内容,比较从ptr1ptr2指针指向的位置开始,向后的num个字节
memcmp的使用需要包含<string.h>

参数

  • ptr1:指针,指向一块待比较的内存块
  • ptr2:指针,指向另外一块待比较的内存块
  • num:指定的比较长度,单位是字节

返回值

返回值 含义
>0 ptr1内存块数据大于ptr2(以unsigned char值比较)
=0 ptr1与ptr2内存块数据相等
<0 ptr1内存块数据小于ptr2(以unsigned char值比较)

代码演示

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char buffer1[] = "DWgaOtP12df0";
    char buffer2[] = "DWGAOTP12DF0";
    int n;
    n = memcmp(buffer1, buffer2, sizeof(buffer1));

    if (n > 0) 
        printf("'%s' 大于 '%s'.\n", buffer1, buffer2);
    else if (n < 0) 
        printf("'%s' 小于 '%s'.\n", buffer1, buffer2);
    else
        printf("'%s' 和 '%s' 一样.\n", buffer1, buffer2);

    return 0;
}

总结

如果要比较2块内存单元的数据的大小,可以使用memcmp函数,这个函数的特点就是可以指定比较长度。
memcmp函数是通过返回值告知大小关系的。

相关推荐
我叫洋洋2 分钟前
C ++ [ hello world ]
c语言·c++·算法
SeaTunnel43 分钟前
从 Python Script 地狱到标准化数据集成框架
大数据·开发语言·python·程序员·代码·seatunnel
碎光拾影1 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
天空'之城1 小时前
C 语言工业级通用组件手写 09:CRC32 数据校验
c语言·嵌入式开发·数据校验·crc32·工业级组件
奋发向前wcx1 小时前
y1,y2总复习笔记5 2026.7.19
数据结构·笔记·算法
Marst Code2 小时前
(python)2026Plotly 库评估:交互式可视化到底值不值得引入?
开发语言·python
Miao121312 小时前
微服务 API 测试实践:海外某民宿平台如何构建模式驱动测试基础设施
java·开发语言
CRMEB系统商城3 小时前
开源自建还是SaaS订阅?算一笔3年经济账
java·大数据·开发语言·开源
keyipatience4 小时前
线程栈与TLS和线程互斥
java·linux·服务器·开发语言·ubuntu
我的xiaodoujiao4 小时前
快速学习Python基础知识详细图文教程9--函数进阶
开发语言·python·学习·测试工具