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函数是通过返回值告知大小关系的。

相关推荐
unityのkiven2 小时前
如何通过DirectShow用C++实现PTZ相机的控制?
开发语言·c++·数码相机
半夜删你代码·2 小时前
24格半格区间拖拽选择
算法
实心儿儿2 小时前
C++ —— C++11
开发语言·c++
chushiyunen2 小时前
python web框架streamlit
开发语言·前端·python
小辉同志2 小时前
17. 电话号码的字母组合
c++·算法·leetcode·深度优先
思小瓜……。2 小时前
校园邮箱过期如何激活MATLAB R2022a
开发语言·matlab·激活软件
眷蓝天2 小时前
python基础
开发语言·python
ytttr8732 小时前
MATLAB ViBe算法视频前景提取完整实现
算法·matlab·音视频
迷糊小鬼2 小时前
Button matrix(矩阵按钮) (lv_buttonmatrix)
c语言·开发语言·前端·ui·矩阵