库函数并不是C语言的一部分,它是由人们根据需要编制并提供用户使用的。每一种C编译系统都提供了一批库函数,不同的编译系统所提供的库函数的数目和函数名以及函数功能是不完全相同的。
1.字符串函数
strcmp
函数原型:
功能是比较两个字符串str1和str2,当str1>str2,返回正数;str1=str2,返回0;str1<str2,返回负数。
我们在模拟实现该函数时,利用循环来对这两个字符串函数逐个比较
int my_strcmp(char* str1, char* str2)
{
char* p1 = str1, * p2 = str2;
int i = 0;
while (*(p1 + i) != '\0' && *(p2 + i) != '\0')
{
if (*(p1 + i) != *(p2 + i))
return (*(p1 + i) - *(p2 + i));
i++;
}
return 0;
}
循环的结束条件是,指针指向的字符有一个为'\0',此时代表至少某个字符串结束。
如果指针指向的位置所对应的字符不相同,则返回第一个指针与第二个指针对应数值的差值。
如果循环结束且还没有返回,则证明两条字符串相等。
strncat
函数原型
strncat的功能是将str2中的num个字符接到字符串str1的后面,str1最后面的'\0'被取消,指针的返回值是str1.
下图为strncat的模拟实现
char* my_strncat(char* str1, char* str2, int n)
{
char* p1 = str1;
int i = 0;
while (*(p1 + i) != '\0')
i++;
int j = 0;
for (j = 0; j < n; j++)
{
*(p1 + i + j) = *(str2 + j);
}
*(p1 + i + j) = '\0';
return str1;
}
由于我们最后要返回str1的地址,所以最好把str1的地址储存到另一个变量中
第一个while循环是为了让p1+i代表的指针指向str1的’\0‘标识符,for循环是将str2中的字符逐次连接在str1后面。直到第n个字符链接成功。
2.内存函数
memcpy
函数原型
作用是将一块指定地址的内容从源地址复制到指定地址,num为要复制的字节数,返回值是指向目标地址的指针。
void* my_memcpy(void* destination, const void* source, size_t num)
{
while (num--)
{
*((char*)destination + num) = *((char*)source + num);
}
return destination;
}
由于不知道向函数传入的是什么样的地址类型,因此应该用void*类型来接收。但是void*无法进行加减运算和解引用操作,我们要对他进行一个字节一个字节地复制,这时就要将其强制转换成char*类型的指针,从要拷贝的数据的最后一个字节开始,向前移动。直到num为0时,将第一个字节拷贝完成。
memmove
函数原型为:
memmove的功能与memcpy的功能相似,只不过memmove是专门用于处理源地址与目标地址重叠的情况
我们设想一下,如果需要把4,5,6复制到3的位置,还像实现memcpy的方法一样,那么6就会把5覆盖住,结果就会变成126666.因此我们要分情况使用不同的方法
当目标地址在源地址的前方时,就要从最前面的数据开始移动,到最后一个数据;
当目标地址在源地址的后方时,就要从最后面的数据开始移动,到最前的数据
void* my_memmove(void* destination, const void* source, size_t num)
{
int i = 0;
if (destination < source)//从前向后
while (num--)
{
*((char*)destination + i) = *((char*)source + i);
i++;
}
else//从后向前
{
while (num--)
*((char*)destination + num) = *((char*)source + num);
}
return destination;
}