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;
}
相关推荐
曙曙学编程5 分钟前
stm32——GPIO
c语言·c++·stm32·单片机·嵌入式硬件
XH华6 小时前
C语言第九章字符函数和字符串函数
c语言·开发语言
♞沉寂9 小时前
信号以及共享内存
linux·c语言·开发语言
SunnyKriSmile9 小时前
【冒泡排序】
c语言·算法·排序算法
_poplar_11 小时前
08.5【C++ 初阶】实现一个相对完整的日期类--附带源码
c语言·开发语言·数据结构·c++·vscode·算法·vim
意疏12 小时前
探秘C语言:数据在内存中的存储机制详解
c语言·开发语言
阿巴~阿巴~1 天前
冒泡排序算法
c语言·开发语言·算法·排序算法
前路不黑暗@1 天前
C语言:操作符详解(二)
c语言·开发语言·经验分享·笔记·学习·学习方法·visual studio
西工程小巴1 天前
实践笔记-VSCode与IDE同步问题解决指南;程序总是进入中断服务程序。
c语言·算法·嵌入式
Nuyoah11klay1 天前
华清远见25072班C语言学习day11
c语言·指针·回调函数