【C语言】内存函数

一、memcpy

(1)函数原型

        它的作用是从source位置开始向后复制num个字节到destination指向的内存位置。它与strcpy函数不同的是,strcpy只针对字符串操作,而 memcpy 是针对内存的复制,所以能对所有类型的num字节数据进行操作。

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

(2)注意事项

  • 因为不是针对字符串的,所以遇到'\0'不会停下来。
  • 如果source内存块与destination内存块有重叠的部分,那么复制的结果是意料之外的。

        例如对于以下代码:

#include<stdio.h>
#include<string.h>

int main() {
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	// 我想把arr的内容改为: 1, 2, 3, 1, 2, 3, 4, 5, 6  
	memcpy(arr + 3, arr, 6 * sizeof(int));
	for (int i = 0; i < sz; i++)
		printf("%d ", arr[i]);
}

        但实际上是这样的:

        最终复制结果是:1, 2, 3, 1, 2, 3, 1, 2, 3

        再来看看VS运行的结果:

        虽然VS中memcpy能正确复制重叠的src到dest,但这只是VS的编译器做到了,C标准中memcpy复制的结果会是1, 2, 3, 1, 2, 3, 1, 2, 3。

        对于重叠的内存复制,由memmove完成。

(3)模拟实现函数

二、memmove

(1)函数原型

        这个函数就是memcpy函数的升级版,它能处理源内存块与目标内存块有重叠的情况。

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

(2)模拟实现函数

        数组下标的增大,所对应的内存地址也增大。

         ① 当 src < dest < src + num 时:

        如果从前往后依次将src的内容复制到dest,那么src的重叠部分内容,会因为前三个元素复制到dest,而被覆盖掉。为了避免这个问题,可以采用从后往前依次复制(从src的结尾开始倒着复制):

        ② 当dest < src 时:

        如果依旧用从后往前复制,会发现 4 和 5 会被先复制过来的 8和7覆盖掉,造成同样的问题。所以这时应该从前往后复制。

        当 dest > src + num 时:

        因为没有重叠的地方,所以从前往后和从后往前复制都是可以的。但是在写代码的时候,为了跟 src < dest < src + num 的情况统一为 dest > src,故使用从后往前的顺序复制。

        代码及运行结果:

三、memset

(1)函数原型

        它的作用是将 ptr 指向的大小为num字节的内存块,按字节为单位设置为value。

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

(2)函数的使用

        如果将value改为1:

        会发现每个元素的值并不为1,而是一个很大的数,这是因为memset是按字节设置值的,所以每一个字节都为设置为01。因此,memset通常是用来将内存块的内容设置为0的。

        但是如果是设置字符数组的内容,就不会出现上面的问题,因为字符的内存大小就是1个字节:

四、memcpy

(1)函数原型

        它的作用的是按字节比较 ptr1 和 ptr2 指向的内存块内容,一共比较num个字节。

        ptr1指向的值比ptr2指向的值小,则返回小于0的数;ptr1指向的值比ptr2指向的值大,则返回大于0的数;ptr1指向的值等于ptr2指向的值,则返回等于0的数。

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

(2)函数的使用

        在内存中,数字的存放是低位数放低位地址的内存单元,高位数放高位地址的内存单元。因此,我们平时书写1的十六进制是:00 00 00 01,但在内存中存放是倒着的:

        故memcpy比较两个内存块,是先比较低位数,再比较高位数的。

        虽然在这个例子中,参数num是20,但实际上在比较 arr2的第4个元素3时就已经比较出大小了,所以只比较了16个字节就得到了结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值