strlen函数实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int my_strlen(char*p)//返回类型是int型的
{
int count = 0;//来计数的
while (*p)//有些人不理解这个()里啥意思,*p不为零,下面p往后走直到p为零,循环停止
{
p++;
count++;
}
return count;
}
int main()
{
char a1[] = "abcdef";
int tmp = my_strlen(a1);//返回值是int型,所以接收用int
printf("%d", tmp);
return 0;
}
strlen函数的作用是计算从字符串的第一个字符开始一直到'\0'中间的字符个数
2。strcmp函数自定义实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int my_strcmp( const char* s1, const char* s2)//其返回类型是int
{
assert(s1 && s2);//断言s1,s2不是空指针
while (*s1 == *s2)//当两个元素一样比较下一位
{
if (*s1 == '0')//两者相等并且*s1为0说明已经比较完了所以返回0。
{
return 0;
}
*s1++;//取下一位再比较
*s2++;
}
return *s1 - *s2;//与下面的效果一样
//if (*s1 > *s2)
// return 1;
//else
// return -1;
int main()
{
char a1[20] = "acde";
char a2[] = "abcdef";
int tmp = my_strcmp(a1, a2);//函数返回值是int所以用int类型接收
if (tmp > 0)
{
printf(">");
}
if (tmp ==0)
{
printf("=");
}
if (tmp < 0)
{
printf("<");
}
return 0;
}
strcmp的作用是比较两个字符的asscll码值,如果找到一方大,则不需要继续比较下去了。
3.strcpy函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//断言的头文件
char* my_strcpy(char* dest, const char* src)//strcpy函数的返回类型是char*,MSDN可以查到
{//传入的是两个数组所以用指针接收,我们不希望src里面的值改变所以加const
assert(dest && src);//断言两个都不是空指针
char* ret = dest;//先存储dest的首地址,因为后边dest的地址就再在最后面了
//while(*src)
// {
// *dest++=*src++;
// }
//*dest='\0';
//return ret;
while (*dest++ = *src++)//比上面的巧妙之处在不用判断*dest是否为0,因为当src为0,赋值后跳出循环
{
;
}
return ret;
}
int main()
{
char a1[20] = { 0 };//a1指定大小,并且大小要大于源数组,要不拷贝不下
char a2[] = "hello world";
char* cpy=my_strcpy(a1, a2);//返回值是char*,所以用char*接受
printf("%s", cpy);//字符串打印用%s,而%p打印地址
return 0;
}
从函数名字上就能看出拷贝就是把一个字符串拷贝到另一个字符串上面。一定要注意a1[]一定要指定大小,且大小一定要能放下拷贝后的字符串。
4.strstr函数实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
const char* s1 = str1;//str1有const所以为了平衡s1也加一个const
const char* s2 = str2;
const char* cur = str1;//cur的作用是记录s1中s2的一样的首个元素
while (*cur)//可以理解cur是一把尺子头,从头记录
{
s1 = cur;//s1是尺子尾,两者之间如果有和s2一样的则查找成功
s2 = str2;
while (*s1 && *s2 && (*s1 == *s2))
{//三个条件s1,s2不为零,s1=s2,其他跳出循环
s1++;//当*s1=*s2时,s1,s2都往下查找对比下一位
s2++;
}
if (*s2 == '\0')//上面说了*s2=0,说明比对完了也找到了
{
return (char*)cur;//char*时强制类型转换,因为上面说了const,所以要变成char*
}
cur++;//当来到这一步时说明以前一个字符开头时都找不到,所以cur前进一步到下一个,否则就与
//上面的一模一样了,就比如abcdef,刚开始从a开始找但是没找到,所以我下一次要从b开始了
//所以cur++
}
return NULL;//strstr函数如果未找到返回NULL
}
int main()
{
char a1[] = "abcdefabdenf";
char a2[] = "abde";
char* ret = my_strstr(a1, a2);
if (ret == NULL)
{
printf("没有找到子集");
}
else
printf("%s", ret);
return 0;
}
这个是最绕的一个,一定要注意cur与s1,s2三者的关系。
5.strcat函数
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)//再次强调返回值类型是char*(可以实现链式访问)
{
assert(dest && src);
char* ace = dest;//ace存储的是dest的首地址,因为下面它就不在指向首地址就会后移一直到拼接后字符串最后面
while (*dest)//要相拼接肯定在第一个字符串的\0处开始,所以他的作用是找\0
{
dest++;//没有找到就找下一位(*dest我测得也可以)dest是地址加一位的到下一位
}//与*dest其实一样,不理解看指针
while (*dest++ = *src++)
{
;
}
return ace;//返回dest首地址
}
int main()
{
char a1[20] = "opq";//数组1的空间一定要能放下拼接后的字符串,要不就越界了
char a2[] = "abcdef";
printf("%s", my_strcat(a1, a2));//上面说了链式访问这个,就是等价于下面的这个
//char* tmp=my_strcat(a1, a2);
//printf("%s", tmp);
return 0;
}
这个函数的作用是把一个函数拼接到另一个函数上面