尝试模拟常用string.h中的库函数
当我们解决问题的时候,常常会使用一些特别的库函数,这些库函数的出现,大大的方便了我们解决问题,也增加了解题的速度,这些库函数的使用让我们的代码更加简便,易读性也随之提高。既然库函数有这么多好处,我们更应该学会它们的实现一些库函数的方法,这样才能让我们学得更加深刻,使用起来如鱼得水。
这里特别介绍一个assert函数,该函数是用于测试指针是否为空,如果为空返回错误结果,否则为真。
strlen库函数实现
strlen函数是用于求字符串长度的,返回的结果是\0之前的字符个数。
#include<assert.h>
int my_strlen(char* dest)
{
assert(dest);
int count=0;//计数器
while(dest++)
{
count++;
}
return count;//返回计数器
}
这个库函数的自我实现方法有很多种,比如使用下标法,也可以返回他的元素个数,要注意判断该字符串是否为空,然后再进行计数。
strcpy模拟实现
strcpy函数是将sour中的字符串包括\0都拷贝放在dest,然后返回dest。
#include<assert.h>
int* my_strcpy(char* dest,const char* sour)
{
assert(dest&&sour);
char* ret=dest;
while(*sour!=='\0')
{
*(dest++)=*(sour++);
}
*dest='\0';//最后一个字符串要改为‘\0’
return ret;
}
这个函数要注意不能把\0丢掉,还有很多种方法可以实现,比如走一步拷贝一个字符判断条件为sour不能为\0。
strcmp模拟实现
该函数主要用于比较两个字符串的大小,如果str1大则返回大于1的数字,如果srtr2大则返回小于0的数字。
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1&&str2);
int flag = 0;
while(*str1!='\0'&&str2!='\0')
{
if (*str1 != *str2)//字符不同,退出计算
{
break;
}
str1++;
str2++;
}
return *str1-*str2;//相同返回0,不同比较返回结果
}
实现这个函数需要注意把返回值设置好,然后在合适的条件下进行比较返回。
strccat模拟实现
该函数作用是在原来的字符串后面追加一个字符串,这里要注意是在原来的字符串的\0的位置开始,返回值是追加好的字符串。
#include<assert.h>
char* my_strcat(char* dest,const char* sour)
{
assert(dest&&sour);
char* ret = dest;//设置返回字符串
while(*dest)//定位\0
{
dest++;
}
while (*(dest++) = *(sour++))//开始交换
{
;
}
return ret;
}
要先找到\0的位置,然后进行交换。
strstr模拟实现
该库函数是用来找出字串的,如果str2是str1的字串返回字串开始的位置,如果不是返回空。
#include<assert.h>
const char* my_strstr(const char* str1, const char* str2)
{
const char* ret = str1;//设立可能的返回值
while (*ret != '\0')
{
const char *p1 = ret;//定位开始
const char* p2 = str2;
while(*p1 == *p2)//都为0自动退出循环
{
//开始比较
*p1++;
*p2++;
}
if (*p2 == '\0')//str2的结束标志,说明str2为str1的子串
return ret;
ret++;
}
return NULL;
}
该函数要控制每一个字符都可能是str2的开始,所以要每一个可能都过滤一遍。
似乎有点意犹未尽,所以这里再介绍两个内存库函数!!
memcpy模拟实现
该函数是将内存中的字节一个一个进行拷贝,和strncpy有异曲同工之妙,但是strncpy只用于字符串,memcpy是用于所有的数据类型,不管你是什么数据类型,都可以拷贝完成。
#include<assert.h>
void * my_memcpy(void* dest, void* sour, size_t num)//void* 是返回值
{
assert(dest&&sour);
void* ret = dest;//设置返回值
while (num--)
{
*(char*)dest = *(char*)sour;//拷贝
dest = (char*)dest + 1;//向后面的字节遍历
sour = (char*)sour + 1;
}
return ret;
}
这个函数和strncpy十分相似,都是用控制数来控制拷贝的字符数。
memmove模拟实现
该函数是用于拷贝字符串,还可以将本身字符串进行移动拷贝,当使用其他字符串进行自身拷贝时,会发生一些无法控制的错误,为了解决自我拷贝的问题,这个函数巧妙的完成了该项功能。
#include<assert.h>
void *my_memmove(void *dest, const void *src, size_t num)
{
void* ret = dest;
if (src > dest)//当需要位移地址在目标地址后面,使用从前向后法则
{
while (num--)
{
//拷贝
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else//当需要位移的首元素地址在目标地址前面,使用从后向前法则
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);//拷贝
}
}
return ret;
}
这里要注意前面的元素是放在低地址处,后面的是放在高地址处,比较地址大小然后决定使用那个方法。
今天的分享就到这里,希望多多指点,一起向前。