🔥引言
本篇将模拟实现字符串函数,通过底层了解更多相关细节
🌈个人主页:是店小二呀
🌈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.2.1方法一
- [1.2.2 方法二](#1.2.2 方法二)
- [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++;
}
}
【说明】:
- 两个指针指向对应的字符串,逐一拷贝
- 虽然形参
dest
和str
是指针变量,形参不会影响到实参 - 这里
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语言中有所帮助!