C语言----C语言内存函数

news2025/2/22 17:52:45

1.memcpy--内存拷贝--使用和模拟实现 

//memcpy基本格式:
//               目标空间地址       原空间地址        被拷贝的字节个数
//void *memcpy(void * destination, const void * source,size_t num);
//因为内存拷贝拷贝的数据有:整型数据、结构体数据、结构体数据。那么我们就要用到void*进行接收任意类型的数据
//void*指针可以接收任意空间

//size_t num这个是要被拷贝的字节个数
//


//返回的是目标空间的起始地址


int main()
{
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    int arr2[20] = { 0 };
    memcpy(arr2, arr1 + 2, 20);//因为我们要拷贝的是3~7,那么就是5个整型,20个字节

        //因为我们要从3开始进行拷贝
        //恰好因为数组名是首元素的地址,那么3的地址就是arr+2
    //将arr1中的3 4 5 6 7拷贝放到arr2中
    for (int i = 0; i < 20; i++)
    {
        printf("%d ", arr2[i]);
    }
    return 0;
}
//我们要满足目标空间能进行修改
//目标空间足够大

//这个memcpy函数是不会考虑\0的,我让他拷贝多少个字节他就拷贝多少个字节

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

1.这个函数在遇到\0的时候并不会停下来

2.如果source和destination有任何的重叠,复制的结果都是未定义的

memcpy函数最终返回的是目标空间的起始地址

//函数的一种写法:
这个函数最终返回的是目标空间的起始地址
//void* my_memcpy(void *dest, const void*src, size_t num)//目标空间是要进行修改的,但是源头是不能被修改的,所以我们加上const
//{
//    assert(src && dest);//防止两个指针是空指针
//    void* ret = dest;//我们需要先创建一个指针存放最开始的dest,通过ret我们可以找到dest指向的数组
//    //这里的src指向的是数组中3的位置
//    //dest指向的是arr2数组的首元素的位置
//    //拷贝20个字节
//    //void*的指针不能进行直接计算,void*的指针是无具体类型的指针
//    for (int i = 0; i < num; i++)//一对字节一对字节
//    {
//        *(char*)dest = *(char*)src;//强制类型转换再进行解引用就将那一对字节进行交换
//        dest = (char*)dest + 1;//先将dest强制类型转换,在进行+1操作,因为上面的强制类型转换只是暂时的,为了能让dest进行++操作,我们就这样操作
//        src = (char*)src + 1;
//    }
//    return ret;
//}

//函数的另一种写法:
//函数的一种写法:
//这个函数最终返回的是目标空间的起始地址
void* my_memcpy(void *dest, const void*src, size_t num)
{
    assert(src && dest);
    void* ret = dest;
    while (num--)//也是循环num次
    {
        *(char*)dest = *(char*)src;
        dest = (char*)dest + 1;
        src = (char*)src + 1;
    }
    return ret;
}




int main()
{
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    int arr2[20] = { 0 };
    int *p=my_memcpy(arr2, arr1 + 2, 20);//这个函数的作用就是我们在arr1中选择的那部分粘贴在arr2中
    for (int i = 0; i < 20; i++)
    {
        printf("%d ", p[i]);
    }
    return 0;
}


//memcpy函数不负责重叠内存的拷贝,非要使用,结果就是未定义的

//只负责不重叠的内存

函数的返回值是void*类型的数据

这个memcpy函数有三个数据

2.memmove--内存移动--使用和模拟实现 

2.memmove--内存移动--使用和模拟实现

int main()
{
    //将123456拷贝放到34567上面
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    memmove(arr1 + 2, arr1, 20);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr1[i]);
    }//输出结果是1 2 1 2 3 4 5 8 9 10
    return 0;
}
//memmove就是用来处理这些重叠内存的拷贝
void* my_memmove(void *dest, const void*src, size_t num)
{
    void* ret = dest;//将目标空间起始地址记录下来

    assert(dest && src);//保证指针的有效性
    //最开始的dest指向的是3,src指向的是1,字节是20
    if (dest < src)//前-->后
        //目标空间的首元素<拷贝的起始元素--就相当与我们把34567拷贝到12345
        //那么12的位置就是dest<src的位置

    {
        while (num--)//总共拷贝num个字节,那么就是num--,等所有字节拷贝完循环就停止了
        {
            *(char*)dest = *(char*)src;
            //拷贝完一对字节就往后走,进行+1操作
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
    }
    else//后-->前剩下的区域---dest > src
    {
        while (num--)
        {
            //进入循环的时候,num 已经是19了
            //*((char*)dest + num)---找到最后一个字节的位置
            *((char*)dest + num)    =       *((char*)src + num);
        //目标的最后一个位置的字节------    起源空间的最后一个位置
            //将起源的最后一个字节先开始挪动,从最后一个位置依次挪动
            //就是将我们要挪动的那块区域,我们从最右边开始挪动
        }
    }
    return ret;
}
int main()
{
    //将123456拷贝放到34567上面
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    my_memmove(arr1 + 2, arr1, 20);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr1[i]);//1 2 1 2 3 4 5 8 9 10
    }
    return 0;
}

//总之:这个拷贝是分三块区域的,最前面的一块区域满足dest<src
//我们只能从前往后进行拷贝,不然会出错误

//而剩下的两块区域可以同时从后往前进行拷贝,那么我们就将这两块区域放在一起

在C语言标准中,明确规定了memcpy只要能实现不重叠的拷贝就行,重叠的拷贝交给memmove

我们发现vs上面的库函数memcpy函数也能实现重叠内存的拷贝

我们在以后的拷贝中,我们可以用memmove,因为不管是重叠的还是不重叠的都能搞定

3.memset--内存设置--函数的使用 

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

基本格式:

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

ptr就是指向要被填充的内存块的指针

value就是我们想要设置的值是什么

num是设置的字节的大小

int main()
{
    char arr[] = "hello world";
    //将world改成5个x
    memset(arr + 6, 'x', 5);//数组首元素的地址+6就是指向的是w
    printf("%s\n", arr);
    return 0;
}

4.memcmp--内存比较--函数的使用 

4.memcmp--内存比较--函数的使用

内存的比较

什么类型的都能进行比较

int main()
{
    int arr1[] = { 1,2,3,4,5 };
    int arr2[] = { 1,2,3,6,5 };
    int ret=memcmp(arr1, arr2, 16);
    printf("%d\n", ret);//输出的数据就是-1
    //就是说明arr1<arr2
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1847886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三丰云免费虚拟主机和免费云服务器评测

今天我要向大家推荐一款非常优秀的云服务提供商&#xff0c;那就是三丰云。三丰云提供了免费虚拟主机和免费云服务器&#xff0c;为用户提供了便捷高效的云计算服务。首先&#xff0c;让我们来看看三丰云的免费虚拟主机服务。三丰云的免费虚拟主机提供了稳定可靠的服务器资源&a…

【ClickHouse】副本、分片集群 (六)

副本 副本的目的主要是保障数据的高可用性&#xff0c;即使一台ClickHouse节点宕机&#xff0c;那么也可以从其他服务器获得相同的数据。 https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/replication/ 副本写入流程 写入流程如图-18所示: 图-18 写…

信息系统项目管理师 | 信息系统安全技术

关注WX&#xff1a;CodingTechWork 信息安全概念 安全属性 秘密性&#xff1a;信息不被未授权者知晓。完整性&#xff1a;信息是正确的、真实的、未被篡改的、完整无缺。可用性&#xff1a;信息可以随时正常使用。 安全分层 设备安全 设备的稳定性&#xff1a;在一定时间…

Ascend C Add算子样例代码详解

核函数定义 核函数&#xff08;Kernel Function&#xff09;是Ascend C算子设备侧实现的入口。在核函数中&#xff0c;需要为在一个核上执行的代码规定要进行的数据访问和计算操作&#xff0c;当核函数被调用时&#xff0c;多个核都执行相同的核函数代码&#xff0c;具有相同的…

千年古城的味蕾传奇-平凉锅盔

在甘肃平凉这片古老而神秘的土地上&#xff0c;有一种美食历经岁月的洗礼&#xff0c;依然散发着独特的魅力&#xff0c;那便是平凉锅盔。平凉锅盔&#xff0c;那可是甘肃平凉的一张美食名片。它外表金黄&#xff0c;厚实饱满&#xff0c;就像一轮散发着诱人香气的金黄月亮。甘…

基于语音识别的智能电子病历(五)电子病历编辑器

前言 首先我们要明确一个概念&#xff1a;很多电子病历的编辑器&#xff0c;在输入文字的地方&#xff0c;有个麦克风按钮&#xff0c;点击一下&#xff0c;可以进行录音&#xff0c;然后识别的文字会自动输入到电子病历中&#xff0c;这种方式其实不能称为“基于语音识别的智…

【MySQL】 -- 事务

如果对表中的数据进行CRUD操作时&#xff0c;不加控制&#xff0c;会带来一些问题。 比如下面这种场景&#xff1a; 有一个tickets表&#xff0c;这个数据库被两个客户端机器A和B用时连接对此表进行操作。客户端A检查tickets表中还有一张票的时候&#xff0c;将票出售了&#x…

Aidlux 1.4 部署Nextcloud 2024.6实录 没成功

Aidux阉割版Debain10&#xff0c;坑很多&#xff0c;比如找不到实际的系统日志&#xff0c;有知道的大神吗&#xff1f; 1 Apache2安装 # 测试Apache2 sudo apt update && sudo apt upgrade sudo apt install apache2 -y80端口疑似被禁止只能换端口 rootlocalhost:/…

云计算技术高速发展,优势凸显

云计算是一种分布式计算技术&#xff0c;其特点是通过网络“云”将巨大的数据计算处理程序分解成无数个小程序&#xff0c;并通过多部服务器组成的系统进行处理和分析这些小程序&#xff0c;最后将结果返回给用户。它融合了分布式计算、效用计算、负载均衡、并行计算、网络存储…

ctr/cvr预估之NFM模型

ctr/cvr预估之NFM模型 在数据驱动的广告和推荐系统中&#xff0c;准确预测用户的点击行为&#xff08;Click-Through Rate, CTR&#xff09;和转化行为&#xff08;Conversion Rate, CVR&#xff09;是提升营销效率和用户体验的关键。因子分解机&#xff08;Factorization Mac…

RK3568技术笔记七 安装Ubuntu Linux

在新弹出的窗口中&#xff0c;单击“CD/DVD &#xff08;SATA&#xff09;”。如下图所示&#xff1a; 在右侧选择“使用ISO映像文件”。然后单击“浏览”&#xff0c;找到SAIL-RK3568开发板光盘->通用工具->虚拟机Ubuntu->ubuntu-18.04.4-desktop-amd64.iso。最后点击…

韩顺平0基础学java——第28天

p569-591 坦克大战&#xff01;&#xff08;绘图监听事件线程文件处理&#xff09; 绘图 绘图原理 Component类提供了两个和绘图相关最重要的方法: 1. paint(Graphics g)绘制组件的外观 2. repaint()刷新组件的外观。 当组件第一次在屏幕显示的时候,程序会自动的调用paint()…

Dify知识库接入微信

Dify知识库接入微信 看到此文章&#xff0c;相信您已经搭建好了Dify知识库&#xff0c;还没有Dify知识库请先部署好后再来尝试将Dify接入微信 准备材料如下 搭建好的Dify知识库里的api接口和key24小时不关机的服务器一个 &#xff08;推荐浪浪云的服务器简单方便)需要一个微信…

数学建模整数规划学习笔记

与线性规划的本质区别在于决策变量是否取整。 &#xff08;1&#xff09;分支定界法 若不考虑整数限制先求出相应松弛问题的最优解&#xff1a; 若松弛问题&#xff08;线性规划&#xff09;无解&#xff0c;则ILP&#xff08;整数规划&#xff09;无解。 若求得的松弛问题最…

校园任务平台系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;论坛管理&#xff0c;任务咨询管理&#xff0c;用户管理&#xff0c;基础数据管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;任务资讯公告&#…

代码随想录第29天|贪心算法

基础知识 原理: 选择每一阶段的最优解, 从而达到全局最优解套路: 无, 只能举反例, 想不出反例则可以尝试用贪心算法 455. 分发饼干 思路: 使用贪心策略 每次用大饼干满足大胃口的孩子(用小饼干则会浪费)或用小饼干满足小胃口的孩子 一定是遍历孩子, 不能遍历饼干, 否则结果不…

大模型时代,新手和程序员如何转型入局AI行业?

在近期的全国两会上&#xff0c;“人工智能”再次被提及&#xff0c;并成为国家战略的焦点。这一举措预示着在接下来的十年到十五年里&#xff0c;人工智能将获得巨大的发展红利。技术革命正在从“互联网”向“人工智能”逐步迈进&#xff0c;我将迎来新一轮技术革新和人才需求…

鸿蒙开发:【组件启动规则(FA模型)】

组件启动规则&#xff08;FA模型&#xff09; 启动组件是指一切启动或连接应用组件的行为&#xff1a; 启动PageAbility、ServiceAbility&#xff0c;如使用startAbility()等相关接口。连接ServiceAbility、DataAbility&#xff0c;如使用connectAbility()、acquireDataAbili…

MySQL之复制(八)

复制 复制和容量规划 备库什么时候开始延迟 一个关于备库比较普遍的问题是如何预测备库会在何时跟不上主库。很难去描述备库使用的复制容量为5%与95%的区别&#xff0c;但是至少能够在接近饱和前预警并估计复制容量。首先应该古纳差复制延迟的尖刺。如果有复制延迟的曲线图&…

如何将现有系统逐步优化成微服务设计

目录 基础服务改造核心步骤准备阶段实施阶段 基础服务设计 本文诞生于学习架构实践专栏后的深思以及总结&#xff0c;结合公司之前“大泥球”的架构风格&#xff0c;改造服务设计的思维。 改造公司系统服务主要原因&#xff1a;1、代码类似“屎山”&#xff0c;牵一发而动全身&…