C语言内存函数

目录

一.memcpy函数

(1)mempcy函数介绍

(2)模拟实现memcpy

 (3)注意事项

二.memmove函数

(1)memmove函数介绍

(2)模拟实现memmove

 三.memcmp函数

(1)memcmp函数介绍

四.memset-内存设置

(1)memset内存介绍


一.memcpy函数

(1)mempcy函数介绍

内存拷贝函数

说明一:第一个参数是目的地指针,第二个参数是源头指针,第三个参数是拷贝字节的大小,返回值是void*

说明二:memcpy从源头的位置开始向后复制num个字节的数据到目的地的内存位置.

说明三:这个函数遇到'\0'的时候并不会停下来

说明四:如果源头和目的地有任何重叠,复制的结果都是未定义的

举例:

                                                拷贝整形数组

    int arr1[] = { 1,2,3,4,5 };
    int arr2[10] = { 0 }; 
    memcpy(arr2, arr1, sizeof(arr1));   

内存布局:                                memcpy执行后

 整形数组就这样被拷贝了!!

我们在试下拷贝结构体数组

先声明结构体

struct S {
    char name[20];
    int age;
};

 创建两个结构体数组,准备吧arr3拷贝到arr4

    struct S arr3[] = { {"张三",20},{"李四",30} };
    struct S arr4[3] = { 0 };

    memcpy(arr4, arr3, sizeof(arr3));

内存布局:

                        拷贝前                                                                 拷贝后

 可见,结构体数组也能被拷贝过去!!

 

(2)模拟实现memcpy

声明函数

void* my_memcpy(void* dest, const void* src, size_t num) {
	void* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (num--)
	{
		*(char*)dest = *(char*)src;
		++(char*)dest;
		++(char*)src;
	}
	return ret;
}

代码实现:

int main() {
	int arr1[] = { 1,2,3,4,5 };
	int arr2[10] = { 0 }; 
	my_memcpy(arr2, arr1, sizeof(arr3));
	return 0;
}

 (3)注意事项

用上面自己写的函数测试下面的代码,代码的目的是arr自己的前5个元素拷贝到下标起始是2的位置处.

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

输出打印结果. 

 

 结果让人意外,输出的内容与所想的不一样.这是因为数组自己给自己拷贝的时候,已经拷贝的位置数 据发生了变化,这是一种源空间和目标空间出现了重叠的情况

也就是所写的函数存在问题,这就要介绍下一个内存函数了,这个内存函数能解决这个问题

二.memmove函数

(1)memmove函数介绍

说明一:和memcpy差别就是memmove函数处理的原内存块和目标内存块是可以重叠的.

说明二:如果源空间和目标空间出现重叠,就得使用memmove

说明三:第一个参数是目的地指针,第二个参数是源头指针,第三个参数是拷贝字节的大小,返回值是void*

举例:

使用memmove,拷贝前五个元素到第3个位置.

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

打印结果 

(2)模拟实现memmove

声明函数

void* my_memmove(void* dest, const void* src, size_t count) {
	void* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);

	if (dest<src)
	{
		while (count--)
		{
			*(char*)dest = *(char*)src;
			++(char*)dest;
			++(char*)src;
		}
	}
	else
	{
		while (count--)
		{
			*((char*)dest + count) = *((char*)src + count);
		}
	}
	return ret;
}

代码实现:

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

 三.memcmp函数

(1)memcmp函数介绍

说明一:比较从ptr1和ptr2指针开始的num个字节,也就是第一个参数是ptr1指针,第二个参数是ptr2指针,第三个是比较的字节大小

说明二:  返回值分别是1 0 -1,跟strcmp一样

举例:

    int arr1[] = { 1,2,3,4,5 };
    int arr2[] = { 1,2,5,4,3 };
    int ret=memcmp(arr1, arr2, 9);
    printf("%d\n", ret);

输出 

 

 返回的是-1,arr2大于arr1

两个数组的排列大致是这样的

 

 由于两个数组第9的个字节相比较,得03<05,所以返回了-1

 

四.memset-内存设置

(1)memset内存介绍

说明一:内存设置,一块空间设置指定字符

说明二:第一个参数是目的地的指针参数,第二个参数是设置的字符,第三个参数是设置的长度

举例:

    int arr[10] = "";
    memset(arr, '#', 10);

     内存布局:

                              使用前                                                                使用后 

        

 

举第二个例子:

     int arr[10] = { 0 };
    memset(arr, 1, 10);

 内存布局:

                                使用前                                                         使用后                               

             

 可以看出,memset操作的是字节,

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值