文章目录
库函数的模拟实现总结
观前提示:本人才疏学浅,理解能力有限,本文仅供参考,若有那里出错,欢迎指正!!
一. strlen的使⽤和模拟实现
(1).strlen的使用
strlen函数:得到字符串的长度并返回
#include<string.h>
int main()
{
char str[20] = "Hello Word";
int ret = strlen(str);
printf("%d", ret);
return 0;
}
输出的结果为10,就是"Hello Word"字符串的个数。
(2).strlen模拟实现
<1>.递归法
int my_strlen(const char* p)
{
if (*p == '\0')
return 0;
else
return 1 + my_strlen(p + 1);
}
int main()
{
char str[] = { "abc" };
int length = strlen(str);
printf("%d", length);
return 0;
}
<2>.计数器法
int my_strlen(const char* p)
{
int count = 0;
while (*p != '\0')
{
count++;
p++;
}
return count;
}
int main()
{
char str[] = { "abc" };
int length = strlen(str);
printf("%d", length);
return 0;
}
<3>.指针—指针法
int my_strlen(const char* p)
{
char* p2 = p;
while (p != '\0')
{
p++;
}
return p - p2;//指针-指针=他们之间的元素个数
}
int main()
{
char str[] = { "abc" };
int length = strlen(str);
printf("%d", length);
return 0;
}
二. strcpy的使⽤和模拟实现
(1).strcpy的使用
strcpy函数:字符串复制函数把source指向的字符串复制到destination指向的地方
#include<string.h>
int main()
{
char str1[] = "Hello word";
char str2[30] = "xxxxxxxxxxxxxx";//需要注意destination的长度一定要能够存放source
strcpy(str2, str1);
printf("%s", str2);
}
(2).strcpy模拟实现
就是把’\0’之前的字符串复制到dest然后再补上’\0’
#include<string.h>
void my_strcpy(char* dest, char* src)
{
while (*src)
{
*dest = *src;
dest++;
src++;
}
*dest = 0;
}
int main()
{
char str1[] = "Hello word";
char str2[30] = "xxxxxxxxxxxxxx";
my_strcpy(str2, str1);
printf("%s", str2);
}
上述代码中有点啰嗦不够严谨,我们来优化以下
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while ((*dest++ = *src++))//到最后一步src='\0',把'\0'赋值给dest
{ //然后(dest++,src++)整个表达式的值为0跳出循环
;
}
return ret;
}
三. strcat的使⽤和模拟实现
(1).strcat的使用
strcat函数:字符串的拼接,把src的字符串拼接到dest,并且dest中的’\0’会被src的首个字符替换掉
int main()
{
char str[80];
strcpy(str, "these ");
strcat(str, "strings ");
strcat(str, "are ");
strcat(str, "concatenated.");
puts(str);
return 0;
}
(2).strcat模拟实现
首先我们需要找到dest中的’\0’,然后将src中的字符串复制过去
void my_strcat(char* dest, char* src)
{
assert(dest != NULL);
assert(src != NULL);
//先找到dest中的'\0'
while (*dest)
{
dest++;
}
//然后就和字符串复制一样
while ((*dest++ = *src++))
{
;
}
}
int main()
{
char str[80] = { "Are " };
my_strcat(str, "these ");
my_strcat(str, "strings ");
my_strcat(str, "are ");
my_strcat(str, "concatenated?");
puts(str);
return 0;
}
四. strcmp的使⽤和模拟实现
(1).strcmp的使用
strcmp函数:比较两个字符串大小,比较两个字符串中对应位置上字符ASCII码值的大小,若str1 > str2返回大于0的数,若str1 = str2返回0,若str1 < str2返回小于0的数,在vs中返回值固定为1,0,-1
int main()
{
char str1[] = { "abd" };
char str2[] = { "abc" };
int ret = strcmp(str1, str2);
printf("%d \n", ret);
return 0;
}
(2).strcmp模拟实现
首先判断是否相等,若相等两指针++,若不相等返回两字符的差值,如果两指针同时等于 ‘\0’ 则两字符串相等返回0
int my_strcmp(char* str1, char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')//因为str1和str2已经相等了,就只用写一个条件就可以
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char str1[] = { "abc" };
char str2[] = { "abc" };
int ret = my_strcmp(str1, str2);
printf("%d \n", ret);
return 0;
}
五. strncpy的使⽤和模拟实现
(1).strncpy的使用
strncpy函数:复制字符串src到dest,但是只复制n个字符
int main()
{
char str1[] = "Hello word";
char str2[30] = "xxxxxxxxxxxxxx";
strncpy(str2, str1,5);//n=5,所以只复制Hello这5个字符
printf("%s", str2);
}
(2).strncpy模拟实现
void my_strncpy(char*dest,char*src,size_t n)
{
assert(dest && src);
int i;
for (i = 0; i < n; i++)
{
*dest++ = *src++;
}
}
int main()
{
char str1[] = "Hello word";
char str2[30] = "xxxxxxxxxxxxxx";
my_strncpy(str2, str1,5);
printf("%s", str2);
}
六. strncat的使⽤和模拟实现
(1).strncat的使用
strncat函数:把src拼接到dest,但是只拼接num个字符
int main ()
{
char str1[20];
char str2[20];
strcpy (str1,"To be ");
strcpy (str2,"or not to be");
strncat (str1, str2, 6);
puts (str1);
return 0;
}
(2).strncat模拟实现
void my_strncat(char* dest, char* src,size_t n)
{
assert(dest != NULL);
assert(src != NULL);
//先找到dest中的'\0'
while (*dest)
{
dest++;
}
int i;
for (i = 0; i < n; i++)
{
*dest++ = *src++;
}
}
int main()
{
char str[80] = { "Are " };
my_strncat(str, "these ",3);
puts(str);
return 0;
}
七. strncmp的使⽤和模拟实现
(1).strncmp的使用
strncmp函数:比较str1和str2函数的num个字符
void test1()
{
char str1[] = "abc";
char str2[] = "abd";
int ret = strncmp(str1, str2, 2);
printf("%d \n", ret);
}
void test2()
{
char str1[] = "abc";
char str2[] = "abd";
int ret = strncmp(str1, str2, 3);
printf("%d \n", ret);
}
int main()
{
test1();
test2();
return 0;
}
(2).strncmp模拟实现
int my_strcmp(const char* p1, const char* p2)
{
assert(p1 && p2);
while (*p1 == *p2)
{
if (*p1 == '\0')
return 0;
p1++;
p2++;
}
return *p1 - *p2;
}
int main()
{
char str1[] = { "abc" };
char str2[] = { "bbc" };
int ret = my_strcmp(str1, str2);
printf("%d ", ret);
return 0;
}
八. strstr的使⽤和模拟实现
(1).strstr的使用
strstr函数:返回字符串str2在字符串str1中第⼀次出现的位置。字符 串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志。
int main()
{
char str[] = "This is a simple string";
char* pch;
pch = strstr(str, "simple");
if (pch != NULL)
strncpy(pch, "sample", 6);
puts(str);
return 0;
}
(2).strstr模拟实现
char* my_strstr(char* str1, char* str2)
{
while (*str2 && *str1 != '\0')
{
char* s1;
char* s2;
if (*str1 == *str2)
{
s1 = str1++;
s2 = str2++;
while (*str1 == *str2 || str2 == '\0')
{
if (*str2 == '\0')
return s1;
else
{
str1++;
str2++;
}
}
str1 = ++s1;
str2 = s2;
}
else
str1++;
}
return(NULL);
}
int main()
{
char str1[] = { "wopword" };
char str2[] = { "word" };
char* p = my_strstr(str1, str2);
if (p == NULL)
printf("未能在str1中找到该字符串\n");
else
puts(p);
return 0;
}
九.memcpy的使⽤和模拟实现
(1).memcpy的使用
memcpy函数: 从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 这个函数在遇到 ‘\0’ 的时候并不会停下来。 如果source和destination有任何的重叠,复制的结果都是未定义的。
int main()
{
int arr1[10];
int arr2[] = { 1,2,3,4,5,6,7,8,9,10 };
memcpy(arr1, arr2, sizeof(arr2));//把arr2中的内容复制10*sizeof(int)个字节
int i;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
(2).memcpy模拟实现
void* my_memcpy(void* scr,void* dest,int num)
{
void* ret = dest;
assert(scr && dest);
while (num--)
{
*(char*)dest = *(char*)scr;
((char*)dest)++;//要加()在++前!!!
((char*)scr)++;//要加()在++前!!!
}
return ret;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
my_memcpy(arr, arr2, 5 * sizeof(int));
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
十.memmove的使⽤和模拟实现
(1).memmove的使用
和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。 如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1+3, arr1, sizeof(int)*3);
int i;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
(2).memmove模拟实现
void* my_memmove(void* dest, void* src, int num)
{
assert(dest && src);
if (dest >= src)
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
else
if (dest < src)
{
while (num--)
{
*(char*)dest = *((char*)src);
((char*)dest)++;
((char*)src)++;
}
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6 };
//my_memmove(arr+1, arr, 3 * sizeof(int));
my_memmove(arr, arr + 1, 3 * sizeof(int));
int i = 0;
for (i = 0; i < 6; i++)
{
printf("%d\n", arr[i]);
}
return 0;
}