本篇文章是对 C 语言常见库函数的模拟实现内容上的介绍与讲解,相信各位看完之后肯定会对 C 语库函数有进一步的认识与理解。如果各位有发现任何错误或者需要更为细致的讲解欢迎各位评论或私信。
本文所用的代码与板书:本文全部代码与板书
本文所用到的网页链接:cplusplus.com
注:本文的板书部分有对相关库函数描述部分,如果各位有时间建议去看看。
目录
前言
众所周知,C 语言的函数是分为库函数和自定义函数。库函数是 C 语言本身所给的函数加上头文件之后可以直接使用。自定义函数是需要程序员自己所编写的,编写完成之后在需要其功能的时候直接引用实现。
相信各位在使用库函数的时候也在好奇库函数的代码与使用逻辑,下面我们废话不多说直接开始搞代码。
strlen
我们通过: cplusplus.com 这个网站可以看到 strlen 函数的组成部分下述部分。
PS:size_t 类型表示C 中任何对象所能达到的最大长度。它是无符号整数,因为负数在这里没有意义。它的目的是提供一种可移植的方法来声明与系统中可寻址的内存区域一致的长度。
函数的参数部分为字符串,此字符串被const所修饰以防被修改,返回字符串长度。
功能:求字符串个数。遇到字符串结尾的'\0'结束。
代码实现:
#include <string.h>//头文件
int main()
{
char str[20] = "hunteryyds";
int ret = strlen(str);
printf("%d", ret);
return 0;
}
知道其功能和参数类型我们就可以写出自己的strlen函数
int my_strlen(const char* str)
{
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
int main()
{
int ret = my_strlen(str);
printf("my_strlen:%d", ret);
return 0;
}
PS:我们知道 '\0' 的十进制数字是 0,所以当 str 字符串 ++ 到 '\0'的时候解引用变成 0 ,while 循环为假。
strcpy
strcpy 函数的组成部分下述部分
代码实现:
#include <string.h>
int main()
{
char str1[20] = { 0 };
strcpy(str1, "hunteryyds");
printf("%s", str1);
return 0;
}
知道其功能和参数类型我们就可以写出自己的strcpy函数
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL && src != NULL);
while ((*dest++ = *src++))
{
;
}
return ret;
}
int main()
{
char str[20] = { 0 };
my_strcpy(str, "hunteryyds");
printf("my_strcpy:%s", str);
return 0;
}
注:对于assert函数想了解的可以自行查阅或者点击我的板书部分。
strcat
strcat 函数的组成部分下述部分:
代码实现:
#include <string.h>
int main()
{
char str1[20] = "hunter";
strcat(str1, "yyds");
printf("%s\n", str1);
return 0;
}
知道其功能和参数类型我们就可以写出自己的strcat函数
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL && src != NULL);
while (*dest)
{
dest++;
}
//while循环找到被插入最后一位
while ((*dest++ = *src++))
{
;
}
return ret;
}
int main()
{
char str1[20] = "hunter";
my_strcat(str1, "yyds");
printf("%s\n", str1);
return 0;
}
输出效果:
strstr
strstr 函数的组成部分下述部分:
代码实现:
#include <string.h>
int main()
{
char p1[20] = "hunteryyds";
char p2[] = "yyds";
char *p = strstr(p1, p2);
if (p == NULL)
{
printf("不存在\n");
}
else
{
printf("%s\n",p);
}
return 0;
}
知道其功能和参数类型我们就可以写出自己的strstr函数
#include <assert.h>
char* my_strstr(const char* p1, const char* p2)
{
assert(p1 != NULL && p2 != NULL);
char* s1 = NULL;
char* s2 = NULL;
char* cur = (char*)p1;
//如果p2是空的,没有给任何数据,里面只有'\0'
if (*p2 == '\0')
{
return (char*)p1;
}
while (*cur)
{//如果前面字符相同,字符跟着查找,之后发现不一样,其开始的位置不知道
//所以要给个"标记"=>cur
s1 = cur;
s2 = (char*)p2;
while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cur;//找到字符串
}
if (*s1 == '\0')
{
return NULL;
}
cur++;
}
return NULL;//找不到字符串
}
int main()
{
char p1[20] = "hunteryyds";
char p2[] = "yyds";
char* p = my_strstr(p1, p2);
if (p == NULL)
{
printf("字符串不存在\n");
}
else
{
printf("%s\n", p);
}
return 0;
}
输出效果:
strcmp
strcmp 函数的组成部分下述部分:
代码实现:
#include <string.h>
int main()
{
char str1[] = "hunteryyds";
char str2[] = "hunternb";
printf("%d", strcmp(str1, str2));
return 0;
}
知道其功能和参数类型我们就可以写出自己的 strcmp 函数
#include <assert.h>
int my_strcmp(char* str1, char* str2)
{
assert(str1 && str2);
//比较
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
*str1++;
*str2++;
}
if (*str1 < *str2)
{
return -1;
}
if (*str1 > *str2)
{
return 1;
}
}
int main()
{
char* p1 = "hunteryyds";
char* p2 = "hunternb";
int ret = my_strcmp(p1, p2);
printf("%d\n", ret);
return 0;
}
memcpy
memcpy 函数的组成部分下述部分:
代码实现:
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[5] = { 0 };
printf("memcpy前:");
for (int i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
memcpy(arr2, arr1, sizeof(arr1));
printf("\nmemcpy后:");
for (int i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
知道其功能和参数类型我们就可以写出自己的 memcpy 函数
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest != NULL && src != NULL);
while (num--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[5] = { 0 };
printf("memcpy前:");
for (int i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
my_memcpy(arr2, arr1, sizeof(arr1));
printf("\nmemcpy后:");
for (int i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
memmove
memmove 函数的组成部分下述部分:
代码实现:
#include <string.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7 };
printf("memmove前:");
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
memmove(arr + 3, arr, 20);
printf("\nmemmove后:");
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
知道其功能和参数类型我们就可以写出自己的 memmove 函数
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t count)
{
void* ret = dest;
assert(dest != NULL && src != NULL);
if (dest < src)
{
//前->后
while (count--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
}
else
{
//后—>前
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
//C语言标准:
//memcpy 只要处理不重叠的内存拷贝就可以
//memmove 处理重叠内存的拷贝
int main()
{
int arr[10] = { 1,2,3,4,5,6,7 };
printf("memmove前:");
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
my_memmove(arr + 3, arr, 20);
printf("\nmemmove后:");
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
后语
希望各位在翻阅过本篇文章各位能够对 C 语言结构体内存有更加深刻的印象。
希望能对各位有所帮助,如果各位有任何疑问,欢迎各位留言,我们可以进行友好的探讨与交流。
欢乐的时间总是过得特别快。又到时间讲bye,我们下一篇再见!!!