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 小时前
5G上行DCI字段判定:端口 流数 PMI选择详解
java·算法·5g
xieliyu.2 小时前
Java算法精讲:双指针(二)
java·开发语言·算法
何以解忧,唯有..3 小时前
Python包管理工具pip:从入门到精通
开发语言·python·pip
wayz113 小时前
Momentum:PSL(心理线指标)技术指标详解
算法·金融·数据分析·量化交易·特征工程
雪的季节3 小时前
RabbitMQ详解
开发语言
8Qi83 小时前
LeetCode 213:打家劫舍 II(House Robber II)—— 题解 ✅
算法·leetcode·职场和发展·动态规划
ice8130331814 小时前
【Python】Matplotlib折线图绘制
开发语言·python·matplotlib
三品吉他手会点灯4 小时前
C语言学习笔记 - 44.运算符和表达式 - 运算符2 - 除法与取余运算符
c语言·开发语言·笔记·算法
kkeeper~4 小时前
0基础C语言积跬步之动态内存管理
c语言·开发语言
橘右今4 小时前
2026 Java后端高频面试宝典
java·开发语言·面试