C 语言常见库函数的模拟实现

        本篇文章是对 C 语言常见库函数的模拟实现内容上的介绍与讲解,相信各位看完之后肯定会对 C 语库函数有进一步的认识与理解。如果各位有发现任何错误或者需要更为细致的讲解欢迎各位评论或私信。

本文所用的代码与板书:本文全部代码与板书

本文所用到的网页链接:cplusplus.com

注:本文的板书部分有对相关库函数描述部分,如果各位有时间建议去看看。 


目录

前言

strlen

代码实现:

strcpy 

代码实现:

strcat

代码实现:

strstr 

代码实现: 

strcmp

代码实现: 

memcpy

​编辑

代码实现:

memmove

代码实现:

后语


前言

        众所周知,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,我们下一篇再见!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值