C语言(九)----C语言内存函数

C语言内存函数

memcpy使用和模拟实现

memcpy使用

c 复制代码
void* memcpy(void* destination(目标),const void* source(源头),size_t num(字节));

memcpy会把source指向位置的内容拷贝到destination指向内存的位置,拷贝大小是num个字节 ,注意在正常拷贝的过程中,memcpy函数遇到\0并不会停止 ,而是在拷贝目标字节数之后停止,即会将\0一同拷贝到目标位置

例如:

将数组arr1在的数据拷贝到数组arr2中

c 复制代码
#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[5] = {1,2,3};
	int arr2[5] = { 0 };
	int i = 0;


	memcpy(arr2, arr1, 20);
	for(i = 0; i< 5;i++)
	{
		printf("%d ",arr2[i]);
	}
	return 0;
}

memcpy模拟实现

在模拟实现 memcpy函数的功能时,我们要了解,该函数时是内存拷贝,对于内存拷贝有以下解释:

内存拷贝:只关注要拷贝的数据在哪里,要存放到哪里,拷贝几个字节,至于内存中存放什么数据,什么类型的数据,都不重要

通常使用memcpy函数拷贝不重叠的内存的数据,memcpy函数不保证重叠内存的拷贝,而对重叠内存的拷贝使用memmove

既然是内存拷贝,那么我们事先就不知道要拷贝数据的类型,所以我们使用了void*来表明指针dest和src所指向数据的不确定性,我们可以想到,char类型的数据在存储时,是只占用一个字节的,那么我们就可以用一个循环,逐字节的拷贝数据,而我们在拷贝的过程中要使用指针,所以需要assert断言指针不为NULL

分析好之后,下面呢就是具体的模拟实现操作

c 复制代码
#include<stdio.h>
#include<string.h>
#include<assert.h>

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

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };

	my_memcpy(arr2,arr1,20);

	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d " ,arr2[i]);
	}

	return 0;
}

memmove的使用和模拟实现

c 复制代码
void* memmove ( void* destination, const void* source, size_t num );

上面我们提到,memmove函数能够实现重叠内存的拷贝,那究竟是怎么做到的呢?其实是因为在拷贝之前,我们进行了判断,判断在拷贝时是从前向后拷贝,还是从后向前拷贝,这样我们可以很好的解决内存重叠的问题

看着图片我们可以很直观的分析,

假设我们将2345所处位置的内容拷贝到3456中,如果我们从前向后拷贝的话,2变成3,那原来位置的3就已经被拷贝成了2,我们想要将3拷贝到4位置的时候,从原来3的位置取出的就变成了2,以此类推,其余的结果也发生了偏差

这种情况是我们不想看到的,其实解决方法也很简单,只需要将2345的内容从后向前拷贝就可以了。

反之如果我们想要将3456的内容拷贝到2345中,只需要从前向后拷贝就可以了

接下来是模拟实现

c 复制代码
#include<stdio.h>
#include<string.h>
#include<assert.h>

void* my_memmove(void* dest, void* src, int n)
{
	void* ret = dest;
	assert(dest && src);
	//当源头在目标空间右边时,从前向后拷贝
    //(char*)dest >= ((char*)src + n)这段代码是说当src与dest没有重叠时,任何拷贝     //方式都可以
	if (dest <= src || (char*)dest >= ((char*)src + n))
	{
		while (n--)                                  
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	//当源头在目标空间左边时,从后向前拷贝
	else
	{
		dest = (char*)dest + n - 1;
		src = (char*)src + n - 1;
		while (n--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest - 1;
			src = (char*)src - 1;
		}
	}

	return ret;
}

int main()
{
	int str1[10] = { 1,2,3,4,5,6,7,8,9,0 };
	int str2[20] = { 0 };

	my_memmove(str1+4, str1, 20);

	int  i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", str1[i]);
	}
	return 0;
}

memset的使用

c 复制代码
void * memset ( void * ptr, int value, size_t num(字节) );

memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。

c 复制代码
#include <stdio.h>
#include <string.h>

int main () 
{ 
	char str[] = "hello world"; 
    memset (str,'x',6);

    printf(str);

    return 0;
}

memset功能效果图:

memcmp的使用

c 复制代码
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

用来比较两个内存块的

⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节

返回值

如果pstr1指向的字符串大于pstr2指向的字符串,那么返回大于0的数

如果等于,返回0

如果小于,返回小于0的数(大多数编译器常为-1)

memcmp模拟实现

c 复制代码
#include<stdio.h>
#include<string.h>
#include<assert.h>

int my_memcmp(const void* str1, const void* str2, size_t n)
{
    assert(str1 && str2);
	while ((char*)str1 == (char*)str2)
	{
		if ((char*)str1 == '\0')
		{
			return 0;
		}
		(char*)str1 = (char*)str1+1;
		(char*)str2 = (char*)str2+1;	
	}
	return (char*)str1-(char*)str2;
}

int main()
{
	char str1[] = "siohoewgh23fk5";
	char str2[] = "siohoewgh23fk4sjica";

	int n = memcmp(str1, str2, sizeof(str1));
	
	if (n > 0)
	{
		printf("str1>str2");
	}
	else if (n < 0)
	{
		printf("str1<str2");
	}
	else
	{
		printf("str1=str2");
	}
	return 0;
}
相关推荐
啊我不会诶2 小时前
篮球杯软件赛国赛C/C++ 大学 B 组补题
c语言·c++
laocooon5238578865 小时前
win操作系统安装C++语言开发环境之一, vscode +MinGW ,流程
c语言
奔跑吧邓邓子5 小时前
解锁Vscode:C/C++环境配置超详细指南
c语言·c++·vscode·配置指南
小柯博客13 小时前
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(十二)
c语言·stm32·单片机·嵌入式硬件·php·嵌入式
乄夜17 小时前
嵌入式面试高频(5)!!!C++语言(嵌入式八股文,嵌入式面经)
c语言·c++·单片机·嵌入式硬件·物联网·面试·职场和发展
乖乖是干饭王19 小时前
Linux系统编程中的_GNU_SOURCE宏
linux·运维·c语言·学习·gnu
weixin_4786897619 小时前
C++ 对 C 的兼容性
java·c语言·c++
待什么青丝20 小时前
【TMS570LC4357】之相关驱动开发学习记录2
c语言·arm开发·驱动开发·单片机·学习
小柯博客20 小时前
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
c语言·stm32·单片机·嵌入式硬件·物联网