浅析如何利用指针实现一些c语言库函数

1.前言

2.库函数的具体作用

3具体实现代码

1.前言

在一些互联网公司的笔试或者面试中,对库函数的考察几乎是必不可少的,或者会问一些库函数之间的区别,或者他们的具体实现方法,那么在本文我将抛砖引玉讲解部分c语言中的库函数的实现,供大家学习参考。

2.库函数的具体作用

今天我们要介绍的库函数主要有memcpy以及memmove,但是所谓知己知彼,方能百战不殆。

我们首先来看看这些库函数具体是如何定义的。

首先看到memcpy函数的描述

C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1

再看到memcpy的参数

  • str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
  • str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
  • n -- 要被复制的字节数。

最后是他的返回值

该函数返回一个指向目标存储区 str1 的指针。

然后我们看到第二个memmove函数的描述

C 库函数 void *memmove(void *str1, const void *str2, size_t n) 从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。

其余参数部分及返回值与memcpy类似我就不再过多赘述。

但是有一点需要注意的是memmove是能够实现在重叠内存块上的复制,而memcpy函数在c语言的标准中对此是不做要求的(虽然现在大多数编译器的memcpy也能实现memmove的功能)。

3.具体实现代码

我们先看到memcpy函数

void* my_memcpy(void*dest,const void*src,int count)
{
	void *ret=dest;//返回值
	assert(dest&&src);//确保传入参数不为NULL
	while(count--)
	{
		*(char*)dest=*(char*)src;//复制过程
		dest=(char*)dest+1;
		src=(char*)src+1;//指针偏移1位
	}
	return ret;
}

这里注意由于void*类型的指针是不能被操作的,只能用于接收各类型的指针,所以使用前必须进行强制类型转换。而转换成char*类型是因为这个库函数是对内存上的每一字节进行修改的,而char*类型的指针每次进行解引用(*)操作或者进行加减,都是操作一个字节,符合该库函数的要求

接下来我们看到memmove函数是如何实现的

void * my_mommove(void*dest,const void*src,int count)
{
	void *ret=dest;
	assert(dest&&src);
	if(dest<src)
	{
		while(count--)
		{
			*(char*)dest=*(char*)src;//从前往后
			dest=(char*)dest+1;
			src=(char*)src+1;
		}
	}
	else
	{
		while(count--)
		{
			*((char*)dest+count)=*((char*)src+count);//从后往前
		}
	}
	return ret;
}

对于memmove函数我们有一点是需要注意的

有两种特殊情况:

(1)src>dest。这种情况下我们需要令src从后往前开始复制给dest串,否则会出现src的值先被覆盖导致得不到想要的结果。

浅析如何利用指针实现一些c语言库函数

 (2)src<dest。对于这种情况,我们需要令src从前往后开始复制给dest串,否则也会出现src的值先被覆盖的情况

浅析如何利用指针实现一些c语言库函数

 (3)如果对于两内存区域没有交叉区域的情况下,那么复制方向不会影响答案的正确性。

所以我们可以得出以下的关系

if(dest<src)//前—>后

else//后——>前

于是便得到了我们上面的代码。

本文就此结束。由于博主能力有限,文章若有任何的错误或者bug可在评论区下方指正。

上一篇:性能测试之Locust


下一篇:angular请求头部加XSRF-TOKEN