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;
}
相关推荐
qystca2 小时前
洛谷 P1157 组合的输出 C语言
c语言·数据结构·算法
艾妮艾妮2 小时前
用函数实现模块化程序设计(七)--数组作为函数参数(排序算法)
c语言·算法·c#·排序算法
Heris993 小时前
零基础快速掌握——【c语言基础】数组的操作,冒泡排序,选择排序
c语言·开发语言·ubuntu·vim
混迹网络的权某4 小时前
蓝桥杯真题——砍竹子(C语言)
c语言·算法·蓝桥杯
shdbdndj4 小时前
C语言:指针与数组
c语言
zxctsclrjjjcph5 小时前
【C++】AVL树
java·c语言·开发语言·数据结构·c++·avl
A5rZ5 小时前
关于c的子进程 fork()
c语言
就爱学编程5 小时前
重生之我在异世界学编程之C语言:深入指针篇(下)
java·c语言·javascript
Uu_05kkq5 小时前
电脑关机的趣味小游戏——system函数、strcmp函数、goto语句的使用
服务器·c语言·电脑
就爱学编程6 小时前
重生之我在异世界学编程之C语言:深入指针篇(上)
c语言·开发语言