完全自学C(干货) —— 内存操作函数

目录

memcpy

memmove

memcmp

memset


内存操作函数

  • memcpy
  • memmove
  • memset
  • memcmp

memcpy

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

  • 复制指定个数字节数据,到目标位置;
    • 遇到'\0'并不会停下来;
    • 如source和destination有任何的重叠也可使用,但一般使用memmove;

注:模拟实现的函数,无法自己拷贝重叠,会覆盖数据;

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 0 };
	int arr2[10] = { 0,1,2,3,4,5,6,7,8,9 };
	//将arr2数组中,前20个字节数据复制到arr1中
	memcpy(arr1, arr2, 5 * 4);
	return 0;
}
#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟实现memcpy
void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest);
	assert(src);
	void* tmp = dest;
	while (num--)
	{
		*((char*)dest)++ = *((char*)src)++;
	}
	return tmp;
}

int main()
{
	char str1[] = "abcdefg";
	char str2[] = "qwe";
	printf("%s ", (char*)my_memcpy(str1, str2, 3));
	return 0;
}
int main()
{
    //会出现覆盖错误
	char str1[] = "abcdefg";
	printf("%s ", (char*)my_memcpy(str1+2, str1, 3));
	return 0;
}
//结果:abafg

int main()
{
	char str1[] = "abcdefg";
	printf("%s ", (char*)memcpy(str1 + 2, str1, 3));
	return 0;
}
//结果:abcfg

memmove

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

  • 复制指定个数字节数据,到目标位置;
    • 与memcpy的差别,处理的源内存块和目标内存块是可以重叠的;
    • 源空间和目标空间出现重叠,使用memmove函数;
#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟实现memmove
void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest);
	assert(src);
	void* tmp = dest;
	//dest<src(dest在前),从前向后拷贝
	if (dest < src)
	{
		while (num--)
		{
			*((char*)dest)++ = *((char*)src)++;
		}
	}
	//dest>=src(dest在后),从后向前拷贝
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return tmp;
}

int main()
{
	char str1[] = "abcdefg";
	char str2[] = "qwe";
	printf("%s ", (char*)my_memmove(str1+2, str1, 3));
	return 0;
}
//结果:abcfg

memcmp

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

  • 比较从ptr1和ptr2指针开始的每个字节无符号值大小,总共比较num个数;
    • <0,ptr1代码块内容小于ptr2代码块内容;
    • =0,ptr1代码块内容等于ptr2代码块内容;
    • >0,ptr1代码块内容大于ptr2代码块内容;

注:和'\0'无关,注意和strcmp/strncmp区分;

#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟实现memcmp,参考strncmp
int my_memcmp(const void* p1, const void* p2, size_t num)
{
	assert(p1);
	assert(p2);
	if (!num)
		return 0;
	while (num--)
	{
		if (*(char*)p1 != *(char*)p2)
		{
			//比较字节无符号值大小
			//大于返回1,小于返回-1
			return (*(unsigned char*)p1 > *(unsigned char*)p2) - (*(unsigned char*)p1 < *(unsigned char*)p2);
		}
		((char*)p1)++;
		((char*)p2)++;
	}
	return 0;
}

int main()
{
	int arr1[] = { 1,222,3,4 };
	int arr2[] = { 1,333 };
	printf("%d ", memcmp(arr1, arr2, 2*4)); //以每个字节值进行比较,num不要越界
	printf("%d ", my_memcmp(arr1, arr2, 2 * 4));
	return 0;
}
//结果:1 1

memset

void* memset(void* destination,int c, size_t num)

  • 设置num字节,每个字节值为c;
    • 将目标地址内num个内存,值设置为c,返回目标空间地址;
    • c为待设置的内存字节值,num指定字节个数;
int main()
{
	char str1[] = "abcdefg";
	printf("%s ", (char*)memset(str1, 'q', 3)); //以每个字节进行设置的
	return 0;
}
//结果:qqqdefg
#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟实现memset
void* my_memset(void* dest, int c, size_t num)
{
	assert(dest);
	void* tmp = dest;
	while (num--)
	{
		*(char*)dest = c;
		(char*)dest += 1;
	}
	return tmp;
}

int main()
{
	char str[] = "abcdefg";
	printf("%s ", (char*)my_memset(str, 'q', 3));
	return 0;
}
//结果:qqqdefg

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值