【C语言】模拟实现深入了解:字符串函数

🔥引言

本篇将模拟实现字符串函数,通过底层了解更多相关细节


🌈个人主页:是店小二呀

🌈C语言笔记专栏:C语言笔记

🌈C++笔记专栏: C++笔记

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅


文章目录

  • 一、模拟实现字符串函数
    • [1.1 模拟实现Strlen](#1.1 模拟实现Strlen)
      • [1.1.1 方法一](#1.1.1 方法一)
      • [1.1.2 方法二:](#1.1.2 方法二:)
      • [1.1.3 方法三:](#1.1.3 方法三:)
    • [1.2 模拟实现Strcpy](#1.2 模拟实现Strcpy)
    • [1.3 模拟实现Strcat](#1.3 模拟实现Strcat)
    • [1.4 模拟实现Strcmp](#1.4 模拟实现Strcmp)
    • [1.5 模拟实现Strncpy](#1.5 模拟实现Strncpy)
    • [1.6 模拟实现Strncat](#1.6 模拟实现Strncat)
    • [1.7 模拟实现Strncmp](#1.7 模拟实现Strncmp)
    • [1.8 模拟实现Strstr](#1.8 模拟实现Strstr)

一、模拟实现字符串函数


1.1 模拟实现Strlen

1.1.1 方法一

c 复制代码
int main()
{
	char arr[] = "abcdef";
	int count = 0;//用于计算累积数
	while (arr[count] != '\0')//'\0'是不在计算的范围
	{
		count++;
	}
	printf("长度为%d\n", count);
	return 0;
}

1.1.2 方法二:

c 复制代码
int main()
{
	char arr[] = "abcdef";
	int tap = 0;
	char* count = arr;//标记字符串的首地址
	while (arr[tap] != '\0') // \0是不在计算的范围
	{
		tap++;
		count++;
	}
	printf("长度为%d", count - arr);//指针-指针等于它们的差值
	return 0;
}

说明】:

  • 通过获得该字符串\0的位置,运用**指针(\0的位置)-指针(首位置)**等于两个指针的差值

1.1.3 方法三:

c 复制代码
int pc(char* arr)
{
	assert(arr);//断言下
	if (*arr == '\0')//设计出口
	{
		return 0;
	}
	{
		return 1 + pc(arr + 1);
	}
}
int main()/
{
	char arr[] = "abcdef";
	printf("长值为%d", pc(arr));
	return 0;
}

说明】:

  • 字符串可以考虑使用大事化小的思想(递归)
  • 观察变化的量,得到等价关系

1.2 模拟实现Strcpy

1.2.1方法一

c 复制代码
void my_strcpy(char* dest, const char* str)
{
	while (*str != '\0')//判断拷贝结束条件
	{
		*dest = *str;//进行拷贝
		dest++;
		str++;
	}
}

说明】:

  • 两个指针指向对应的字符串,逐一拷贝
  • 虽然形参deststr是指针变量,形参不会影响到实参
  • 这里dest传递过来是地址(数组名),对此可以修改dest指向的字符串
  • dest指向的字符串需要被修改,但是src指向字符串不希望被修改

1.2.2 方法二

c 复制代码
char* my_strcpy(char* dest, const char* str
{
    assert(dest != NULL);
    assert(str != NULL);
    char* ret = dest;//标记初始地址
    while (*dest++ = *str++)//判断和后置++打配合
    {
    }
    return ret;
}

说明】:

  • 这里实现逻辑跟方法一类似,只是这里循环判判断条件不同
  • 在循环判断语句中,完成拷贝赋值操作
  • 当str指针指向\0的位置,则表示循环结束
  • \0的ASCII码值是0(为假)

1.3 模拟实现Strcat

c 复制代码
char* my_strcat(char* p, const char* pc)
{
	assert(p != NULL);
	assert(pc != NULL);
	char* ret = p;///标记初始地址
	while (*p != '\0')//找到目标字符串的结束标记
	{
		p++;
	}
	while (*p++ = *pc++)//在结束标记的位置上追加,直到pc找到'\0'
	{
	}
	return ret;///返回初始地址
}

说明】:

  • 第一次循环:找到目标字符串的结束标记
  • 第二次循环:在结束标记的位置上追加,直到pc找到'\0'完成追加操作

1.4 模拟实现Strcmp

c 复制代码
int my_strcmp(const char* p, const char* pc)
{
	assert(p != NULL);
	assert(pc != NULL);
	while (*p == *pc)//不相等才要对比
	{
		if (*p == '\0')//找到结束位置了,说明两个字符串是相等的
		{
			return 0;
		}
		p++;
		pc++;
	}
	return *p - *pc;//用四则运算判断正负
}

说明】:

  • 循环判断是否相同
  • 相同继续向后寻找
  • 不相等则通过四则运算判断正负

1.5 模拟实现Strncpy

c 复制代码
char* my_strncpy(char* p, const char* pc, int sz)
{
	assert(p != NULL);
	assert(pc != NULL);
	char* ret = p;//标记初始地址
	while (sz--)//拷贝次数
	{
	  *p = *pc;//拷贝开始啦!
	   p++; 
       pc++;
	}
	return ret;//返回初始地址
}

说明】:

  • 跟模拟实现strcpy逻辑类似,只是通过一个变量控制循环次数

1.6 模拟实现Strncat

c 复制代码
char* my_strncat(char* p, const char* pc, int sz)
{
	assert(p != NULL);
	assert(pc != NULL);
	char* ret = p;//标记初始地址
	while (*p != '\0')//找到目标字符串的结束标记
	{
		p++;	
	}
	while (sz)//追加次数,注意上篇文章可能的问题
	{
		*p = *pc;
		p++;
		pc++;
	    sz--;	
	}
	return ret;//返回初始地址
}

说明】:

  • 跟模拟实现strcat逻辑类似,只是通过一个变量控制循环次数

1.7 模拟实现Strncmp

c 复制代码
int my_strncmp(const char* p, const char* pc, int sz)
{
	assert(p != NULL);
	assert(pc != NULL);
	
		while (*p == *pc && sz--)//注意不同就是,次数作为判断条件
		{
			if (*p == '\0')//找到结束位置了,说明两个字符串是相等的
			{
				return 0;
			}
			p++;
			pc++;
		}
		return *p - *pc//用四则运算判断正负
	}

说明】:

  • 跟模拟实现strcmp逻辑类似,只是通过变量控制循环次数和是否不出现不相等

1.8 模拟实现Strstr

c 复制代码
char* my_strstr(char* p, char* pc)
{
    assert(p && pc);
    char* dest = p;//标记初始地址
    char* str = pc;//标记初始地址
    
    if (*pc == '\0')//如果是空字符就没有不要了!
    {
        return p; 
    }
    
    while (*dest)//字符串寻找子字符串的次数
    {
        while (*p == *pc  &&  *p  && *pc)//实现逻辑
        {
            p++;
            pc++;
            if (*pc == '\0')//子字符串都对应上了
            {
                return dest;//找到位置的指针返回
            }
        }
        pc = str;//上面可能找到子字符串了,但是可惜不是回归子字符串的地址			
        dest++;
        p = dest;//dest的位置推进,地毯式搜索
    }
    
    if (*dest == '\0')//匹配完,找不到子字符串
    {
        return NULL;
    }
}

说明】:

  • 假设原字符串是ccpd,目标字符串cp
  • 当匹配第一个字符时,可能后继都是匹配的,也可以只是部分匹配
  • 对此需要记录这个匹配位置,通过内循环遍历一次判断是否匹配
  • 如果从这个位置不匹配,则推进一位,继续循环(暴力解法)

以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二C语言笔记,希望对你在学习C语言中有所帮助!

相关推荐
神奇夜光杯2 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue4 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧6 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
EricWang135815 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
测试界的酸菜鱼17 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
我是谁??17 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
Mephisto.java21 分钟前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
晨曦_子画27 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend35 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法