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的值先被覆盖导致得不到想要的结果。
(2)src<dest。对于这种情况,我们需要令src从前往后开始复制给dest串,否则也会出现src的值先被覆盖的情况
(3)如果对于两内存区域没有交叉区域的情况下,那么复制方向不会影响答案的正确性。
所以我们可以得出以下的关系
if(dest<src)//前—>后
else//后——>前
于是便得到了我们上面的代码。
本文就此结束。由于博主能力有限,文章若有任何的错误或者bug可在评论区下方指正。