关于字符串和内存操作的c库函数,我个人认为strstr和memmove应该是模拟最困难的,今天我们就详细的去模拟这两个函数。
1.strstr函数模拟
strstr函数作用:查找字符串中首次出现所要查找的字符串,查找成功,则打印该字符串以及其后的字符,反之,则报错。
例如:
接下来我们就自己模拟一下该函数,当然模拟函数也要去按照原库函数的格式模拟
const char * my_strstr(const char *p, const char *q)
{
assert(p);
assert(q); //检测传入参数是否有意义
const char *_p = p;
const char *_q = q; //保存字符串起始地址
const char *p_start = p; //保存每次比较时的起始地址
while (*p_start){
_p = p_start;
_q = q;
while (*_p&&*_q&&*_p == *_q){
_p++;
_q++;
}
if (*_q == '\0'){
return p_start;
}
p_start++; //下一次比较的起始地址
}
return NULL;
}
写完代码后,我们再来图画模拟一次,
2.memmove函数模拟
menmove函数作用:与memcpy相似,都是复制内存内容,但是相比mencpy,memmove能够更好的解决内存重叠的问题
这就是memmove的基本原理,下面我们来模拟模拟一下
void *my_memmove(void *p,const void *q,size_t num)
{
assert(p);
assert(q); //内存复制是否有意义
int i = 0;
char *_p = (char*)p;
const char *_q = (char*)q; //保存起始地址
while (num > 0){
if (_p > _q&&_p<_q+num){ //内存重叠特殊情况
*(_p + num - 1) = *(_q + num - 1);
num--;
}
else{
*(_p+i) = *(_q+i);
i++;
num--;
}
}
return _p;
}
这就是一个简单的memmove函数模拟,其中有一个内存重叠的特殊情况,我们画图说明
当我们将p的首元素复制给p+1的首元素时,也就相当于改变了p的下一个元素,所以如果只是考虑从起始交换,会导致最后结果为全h,所以我们这里就对这种特殊内存重叠拿出来,让他从最后一个位置开始交换,这样就会避免错误复制。
这就是两个相对比较复杂一点的函数,模拟函数只是去比较清晰的认识这个函数,不过我们在编程中可不敢自己写库中已经存在的函数,既浪费时间,有可能还会有错误,所以,我们要学会变通啊