内存函数memcpy和memmove

memcpy 内存拷贝

函数原型:void * memcpy(void * destination , void * source, size_t num);

  1. 函数mencpy从source的位置开始向后复制num个字符的数据到destinaton的内存位置
  2. 这个函数遇到'\0'并不会停下来
  3. 如果source和destination有任何的重叠,复制的结果都是未定义的
  4. 用于两块独立的内存之间的拷贝
javasScript 复制代码
int main()
{
    int arr1[] = {1, 2, 3, 4, 5, 6, 7};
    int arr2[10] = {0};
    memcpy(arr2, arr1, 28);   //最后一个参数的单位是byte
}

模拟实现memcpy函数,如下:

javaScript 复制代码
void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* p = dest;
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest =(char *)dest + 1;
		src = (char*)src + 1;
	}
	return p;
}

memmove 内存移动

函数原型:void * memmove ( void * destination, const void * source, size_t num );

  1. Copies the values of num bytes from the location pointed by source to the memory block pointed by destination. Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.
  2. 用于同一块内存的覆盖拷贝
javaScript 复制代码
int main ()
{
  char str[] = "memmove can be very useful......";
  memmove (str+20,str+15,11);  //用于同一块内存的覆盖拷贝
  puts (str);
  return 0;
}

输出

javaScript 复制代码
memmove can be very very useful.

memcmp 比较内存中两个数据的大小

函数原型:int memcmp(const void *ptr1, const void * ptr2, size_t num);

  1. 比较从ptr1和ptr2指针开始的num个字节
  2. 返回值如下:
return value indicates
< 0 the first byte that does not match in both memory blocks has a lower value in ptr1 than in ptr2 (if evaluated as unsigned char values)
0 the contents of both memory blocks are equal
> 0 the first byte that does not match in both memory blocks has a greater value in ptr1 than in ptr2 (if evaluated as unsigned char values)
javaScript 复制代码
int main()
{
    int arr1[] = {1, 2, 3, 4, 5};
    int arr2[] = {1, 3, 2};
    int ret = memcmp(arr1, arr2, 12);   //比较是按一个字节一个字节的比较
    printf("%d\n", ret);
}

输出

javaScript 复制代码
-1

memset 内存设置指定的值

函数原型:void * memset(void *ptr, int value, size_t num);

  1. Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).
  2. 按字节设置。

用法一:设置字符的值

javaScript 复制代码
int main ()
{
  char str[] = "almost every programmer should know memset!";
  memset (str,'-',6);
  puts (str);
  return 0;
}

输出

javaScript 复制代码
------ every programmer should know memset!

用法二,设置int型的值

javaScript 复制代码
int main()
{
	int arr[] = { 1, 2, 3, 4, 5 };
	int i = 0;
	memset(arr, 1, 20);
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}
}

输出

javaScript 复制代码
16843009
16843009
16843009
16843009
16843009

由以上结果分析,由于memset是按字节一个一个的来设置value,所以int型的变量,就是被设置为:0x01010101 即为16843009;

随意meset对int型的通常用法是清零:memset(arr, 0 ,20)

相关推荐
xiaobobo33304 小时前
C语言中宏定义宏名和宏值之间的关系
c语言·宏定义·语义型
a4493153628 小时前
MacBook USB-C不充电故障诊断:从PD握手到主板供电链路
c语言·开发语言·macos·电脑
a4493153629 小时前
iPhone 充电故障的全链路诊断——从 Lightning/USB-C 接口到 Tristar 充电 IC
c语言·macos·ios·电脑·硬件架构·iphone
qq_448011169 小时前
C语言中的getchar()
c语言·开发语言
天空'之城9 小时前
C 语言工业级通用组件手写 15:累加和校验
c语言·嵌入式开发·工业级组件·累加和校验
碎光拾影1 天前
i.MX6ULL时钟系统配置指南
c语言·arm开发·嵌入式硬件
GeekArch1 天前
第28讲:避坑——AI堆栈分配错误、栈溢出BUG
c语言·人工智能·stm32·mcu·学习·bug
wuyk5551 天前
59.嵌入式C语言高级宏定义实战:多行宏、字符串化与符号拼接
c语言·开发语言·stm32·单片机·嵌入式硬件·物联网·51单片机
无相求码1 天前
C程序的内存到底怎么分的?栈、堆、全局区一张图讲清楚
c语言
天空'之城1 天前
C 语言工业级通用组件手写 08:精准软件消抖
c语言·嵌入式开发·工业级组件·软件消抖·按键防抖