当前位置: 首页 > news >正文

C语言学习之内存函数

        今天我们来学习一下C语言中内存函数

        以下内存函数的使用均需要包含头文件<string.h>

目录

memcpy函数的使用及其模拟实现

        memcpy函数的模拟实现

memmove函数的使用和模拟实现

        memmove函数的模拟实现

memset函数的使用

memcmp函数的使用


memcpy函数的使用及其模拟实现

        语法结构如下:

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

        memcpy函数从source位置开始向后复制num个字节的数据到destination指向的内存位置

        这个函数在遇到’\0‘的时候不会停下来

        如果source和 destination重叠复制的结果都未知

#include<stdio.h>
#include<string.h>
int main()
{int ar1[] = { 1,2,3,4,5,6,7,8,9,10 };int ar2[10] = {0};memcpy(ar2, ar1,sizeof(ar1));for (int i = 0;i < 10;i++){printf("%d ", ar2[i]);}return 0;
}

        memcpy函数的模拟实现

#include<stdio.h>
#include<string.h>
//函数返回目标空间的起始地址
void my_memcpy(void* dest, const void* src, size_t num)
{//void*指针需要转换,不能直接运算while (num--){*(char*)dest = *(char*)src;src = (char*)src + 1;dest = (char*)dest + 1;}}
int main()
{int ar1[10] = { 1,2,3,4,5,6,7,8,9,10 };int ar2[10] = {0};my_memcpy(ar2, ar1,sizeof(ar1));for (int i = 0;i < 10;i++){printf("%d ", ar2[i]);}return 0;
}

而对于重叠的内存空间,可以交给memmove函数处理

memmove函数的使用和模拟实现

        语法结构:

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

        与memmove函数差别是memmove函数处理的源内存块和目标内存块是可以重叠的 

        如果源内存和目标空间出现重叠,就交给memmove函数处理

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

        结果为:

        memmove函数的模拟实现

        思路:以拷贝5个字节到第三个为起始位置为例:

        

        当将蓝色数据拷贝到红色数据的时候,从后向前;将红色数据拷贝到蓝色数据的时候,从前向后

        因此有如下代码: 

void* my_memmove(void* dest, const void* src, size_t num)
{void* ret = dest;if (dest<src || (char*)dest>(char*)src + num){/*源头在目标前面,或目标在源头后面,则从头开始复制*/while (num--){*(char*)dest = *(char*)src;src = (char*)src + 1;dest = (char*)dest + 1;}}else{/*源头在目标后面,则从尾开始复制*/dest = (char*)dest + num - 1;src = (char*)src + num - 1;while (num--){*(char*)dest = *(char*)src;src = (char*)src - 1;dest = (char*)dest - 1;}}return (ret);
}
int main()
{int ar1[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(ar1, ar1+2,20);for (int i = 0;i < 10;i++){printf("%d ", ar1[i]);}return 0;
}

memset函数的使用

        语法结构:

void* memset(void* ptr, int value, size_t num);

        memset函数是用来设置内存的,将内存中的值以字节为单位设置成想要的内容

#include<stdio.h>
#include<string.h>
int main()
{char str1[] = "hello world";memset(str1, 'a', 6);printf("%s\n", str1);return 0;
}

       结果为:

         

memcmp函数的使用

        语法结构为:

int memcmp(const void *ptr1,const void *ptr2,size_t nums);

        比较ptr1和ptr2指针指向的位置,向后num个字节(即比较前num个字节的大小)

        返回值如下:

         即:

        <0,ptr1小于ptr2

        =0,ptr1等于ptr2

        >0,ptr1大于ptr2

#include<stdio.h>
#include<string.h>
int main()
{char str1[] = "DWAGYftsuibhug";char str2[] = "DWAGYhulu";int n=memcmp(str1, str2, sizeof(char)*10);if (n == 0){printf("str1 is equal to str2\n");}else if (n < 0){printf("str1 is less than str2\n");}else{printf("str1 is greater than str2\n");}my_memcpy(str1, str2, sizeof(char)*5);return 0;
}

        本篇博客就到这里了。求一个点赞,谢谢各位

相关文章:

  • Python打卡训练营day27-函数-装饰器
  • 深入解析MATLAB codegen生成MEX文件的原理与优势
  • MySQL高频面试八连问(附场景化解析)
  • 【MySQL】第六弹——表的CRUD进阶(四)聚合查询(下)
  • 【C# 自动化测试】借助js获取浏览器滚动条高度
  • 2025ICPC武汉邀请赛-F
  • 【c# 类型转换中 as 和()】
  • DAY29 超大力王爱学Python
  • Java异常处理与File类终极指南
  • Java高频面试之并发编程-19
  • 【Qt】在OrinNX上,使用命令安装qtmultimedia5-dev时报错
  • VMware三种网络配置对比
  • 【华为OD- B卷 - 增强的strstr 100分(python、java、c++、js、c)】
  • 如何解决全局或静态变量被修改的bug
  • 高频Java面试题深度拆解:String/StringBuilder/StringBuffer三剑客对决(万字长文预警)
  • SpringBoot 自动配置
  • FEKO许可证与其他电磁仿真软件的比较
  • 2024年热门AI趋势及回顾
  • leetcode 3355. 零数组变换 I 中等
  • PYTHON训练营DAY31
  • 为小龙虾洗清这些“黑锅”,这份科学吃虾指南请收好
  • 存款利率、LPR同日下调,机构称对银行的影响偏正面
  • 国家发改委谈稳定外资:将研究制定鼓励外资企业境内再投资政策措施
  • 安徽凤阳通报鼓楼瓦片脱落:2023年曾维修,已成立调查组
  • 甘肃白银煤矿透水事故仍有3人失联,现场约510立方米煤泥拥堵巷道
  • 被央视曝光“废旧厂区沦为垃圾山”,江西萍乡成立调查组查处