C语言内存函数揭秘:memcpy与memmove深度解析 C 语言的内存函数包含了多个部分, 在这里主要聚焦于这四个方面的内容。函数和函数在本质上是比较类似的, 它们所做的主要工作之一, 就是把某一个数组内部所存在的各种内容, 复制粘贴到另外一个被指定的数组里面去。void * memcpy ( void * destination, const void * source, size_t num )首先, 来关注一点, 那就是它的返回类型, 这个类型为void*, 这样的话, 就意味着这所对应的函数, 是可以针对那些任意类型的所存在的数据执行拷贝操作的。再看看他的参数, 什么意思呢? 意思就是要从开始的位置起, 把num个元素给拷贝到去里面。这个函数在遇到\0字符的时候, 它不会停止执行。倘若它与目标缓冲区存在任何形式的重合或者相交的情况, 那么进行复制操作所产生的结果都属于未定义的状态。我们自己亲手实现一个, 走进他的内部去看一看究竟。首先, 我们需要对事先断言两个选定的空间是不是处于空指针的状态, 而在执行拷贝操作的时候, 它是按照字节为单位来进行的。我们拿拷贝字符串这个例子来说一说, 比方说上面讲到的情况, 我们的目的是要把 s2 里面的元素拷贝到 s1 里面去, 因为这是一个有 6 个字符的字符串, 它一共就占 6 个字节, 那么在执行拷贝操作的时候, 它是按照一个字节接一个字节这样的顺序来处理的, 所以我们在写循环代码的时候, 让那个计数器 num 每次都减 1 就可以了, 也就是说, 有多少个字节我们就拷贝多少个字节, 这里有个细节要注意, 因为指向这些内存的 dest 变量以及那两个形参, 它们的类型都是 void* 类型的, 所以在进行操作之前, 我们需要把它们强制转换成 char* 类型, 然后再对转换过后的指针进行解引用操作, 紧接着再进行数据的拷贝, 每一次成功拷贝完一个字节之后, 那两个负责记录的地址值都需要往后移动一步, 这里必须强调一点是, 一定要先完成类型的转换, 然后再对转换后的指针执行加加 ( ) 操作, 千万不能写成比如 (char*)dest 这种形式, 因为它在语法上就是错误的, 正确的写法必须是先把 dest 括起来转换类型, 再在外面做 ((char*)dest), 等到所有工作都做完了, 函数返回的时候, 我们要返回的是 dest 最初的那个地址, 可以在函数的开头先定义一个类型为 char * 的指针变量, 用它来存好 dest 最开始的地址信息, 然后在最后直接 那个变量就行, 虽然在上面给出的那个例子里面, 我们没有把返回值接住, 仅仅是调用了函数, 这好像没啥影响, 但是为了保证整个程序写得完整规范, 我们还是应该坚持返回起始地址这一做法, 另外补充说明一下, 如果当前要拷贝的数据类型是整数型的话, 那就不需要像上面那样只算字符数了, 而是要仔细计算清楚一共有多少个字节存在。在传递参数的时候, 就必须明确几个字节的数量这一点是必须要铭记于心的, 也就是说目标空间一定要保持足够的大小, 如果不这样做的话就会轻易出现越界这种令人头疼的情况发生。什么是内存重叠 举个例子有一个整型的变量a, 它在定义的时候被初始化成了一个大括号里面包裹着数字1到9的一个集合, 现在需要把这个a里面的元素当中的数字1以及数字2提取出来并复制给它自己, 而且一共要完成复制4个元素的任务在执行复制操作的时候, 所涉及到的内存中的起始地址位置需要从第3号位置开始进行。他这种情况, 是会被出现的。这种情况也就是所谓的内存重叠, 拷贝4个元素, 当拷贝到第三个元素时, 第三个元素已经变成1了, 所以5的位置就变成1而不是。这是由我们自己制作的函数库里面的话, 是不会出现这样的一种情况的, 至于具体他是怎么去写的, 我们的意思就是也是不太了解的这一点, 但总而言之的话, 他的这个逻辑和我们自己写的那个其实都是比较接近的。所以, 当咱们在操作里碰到内存重叠这种状况的时候就可以考虑去使用这个函数, 而这个函数的出现, 就把内存重叠导致的问题给彻底地解决掉了。函数这个函数的功能和它是一样的, 不过是它解决了内存重叠这个问题的。在把数据进行拷贝的过程里, 以下这类的情况是会存在的。假如你仍然有某些不清楚的状况存在, 那么请你及时来跟我进行沟通联系, 这里先向你表达一番感谢。代码快的实现这里需要特别提到一个情况, 那就是咱们得把顺序进行逆转。就比如字符串这个事儿, 如果你是要拷贝5个元素, 那么当你把第一个元素的地址和num那个数值加起来时候, 得到的结果就会变成最后那个元素的地址, 接着你再做num减减的动作, 这样每次操作都会让指针往前面挪动一个位置。所以说呀, 当碰到内存区域出现重叠这种状况的时候, 就必须使用相应的函数去进行处理。这个函数是用来设置内存的, 它以一字节为单位, 将内存设置成你能够想要的内容。void * ( void * ptr, int value, num )第一个空格是用来填写你打算去设定的那个具体的地址, 第二个空格则是用来填写你要填入的具体内容, 至于第三个空格, 它的作用是让你填写你准备设置的那几个元素分别一共有多少个。函数这个 int 是一个用于比较两个元素的大小的函数, 它接收三个参数, 前两个是 const void *类型的指针, 分别表示为ptr1和ptr2, 而第三个参数则是需要比较的元素的数量。⽐较从ptr1和ptr2指针指向的位置开始向后的num个字节这个函数比较简单, 主要是了解它背后的原理, 也就是通过ASCLL值来进行比较的。四个函数全都已经整理完毕了, 对于你所到来的这一事儿, 在这里向你表示谢意。