首先需要知道在c语言中本身并没有字符串类型,字符串通常放在常量字符串中或者字符数组中
1.实现strlen
首先strlen函数的作用是求字符串长度的。'\0’是它的结束标志,strlen函数返回的是在字符串中‘\0’前面出现的字符个数,strlen函数的返回值为size_t,是无符号的,它的实现有三种方式。
第一种用指针和计数器的方式。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int my_strlen(char* str)
{
int count=0;
while(*str)
{
str++;
count++;
}
return count;
}
int main()
{
char str[]="asdvssdvsdv";
printf("%d\n",my_strlen(str));
return 0;
}
这是最简单也是很容易理解的一种方式。
第二种递归的方式。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int my_strlen(char* str)
{
if(*str=='\0')
return 0;
else
return 1+my_strlen(str+1);
}
int main()
{
char str[]="asdvssdvsdv";
printf("%d\n",my_strlen(str));
return 0;
}
第三种是采用指针和指针的方式。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int my_strlen(char* str)
{
char* p=str;
while(*p!='\0')
p++;
return p-str;
}
int main()
{
char str[]="asdvssdvsdv";
printf("%d\n",my_strlen(str));
return 0;
}
2实现strcpy
首先应该知道它的作用是复制,char* strcpy(char* destination,const char* source)目标空间应该足够大,以确保能存放源字符串,源字符串必须以‘\0’结束,会将源字符串的‘\0’拷贝到目标空间。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<assert.h>
#include<algorithm>
using namespace std;
char* my_strcpy(char* dest,char* src)
{
char* ret=dest;
assert(dest!=NULL);
assert(src!=NULL);
while((*dest++==*src++)!='\0')
{;}
return ret;
}
int main()
{
char str1[]="hello";
char str2[]="world";
printf("%s\n",my_strcpy(str1,str2));
return 0;
}
assert是判断指针有效性的函数。是把dest复制到原函数上面。循环写成while(*dest++=*src++)明显是错误的,不知什么时候结束。循环写成while(*src!='\0'){*dest++=*src++;}也是错误的,循环体结束后,dst末尾并没有加上‘\0’.
2.实现strcat
该函数的作用是拼接函数,stract(str1,strr2),str2是源,str1是目标函数,是把源拼接在目标函数上,目标函数必须足够大,能容纳下源字符串的内容。
#include<iostream>
#include<algorithm>
#include<assert.h>
#include<cstdio>
using namespace std;
char *my_strcat(char* dest,char *src)
{
char* ret=dest;
assert(dest!=NULL);
assert(src!=NULL);
while(*dest!='\0')
{
dest++;
}
while((*dest++=*src++))
{
;
}
return ret;
}
int main()
{
char str1[]="hello";
char str2[]="world";
my_strcat(str1,str2);
printf("%s\n",my_strcat(str1,str2));
return 0;
}
3.实现strcmp
该函数的作用是比较另个字符串是否完全相同。此处用返回相关数值表示。返回0表示完全相同,返回1表示不相同。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<assert.h>
using namespace std;
int my_strcmp(char* src,char* dst)
{
assert(src!=NULL);
assert(dst!=NULL);
while(*src==*dst)
{
if(*src=='\0')
return 0;
++src;
++dst;
}
if(*src>*dst)
return 1;
else
return -1;
}
int main()
{
char str1[]="hello";
char str2[]="hellv";
my_strcmp(str1,str2);
cout<<my_strcmp(str1,str2)<<endl;
return 0;
}
4.实现strchr
strchr 原型为extern char *strchr(const char *s,char c),可以查找字符串s中首次出现字符c的位置。此函数并不常用。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<assert.h>
using namespace std;
char* my_strchr(char* str,char c)
{
assert(str!=NULL);
while(*str!='\0')
{
if(*str==(char)c)
{
return (char*)str;
}
str++;
}
return NULL;
}
int main()
{
char str[]="abcdefg";
char *p;
p=my_strchr(str,'f');
if(p==NULL)
{
cout<<"Not Find"<<endl;
}
else
{
cout<<"Find"<<endl;
cout<<p<<endl;
}
return 0;
}
5.实现strstr
strstr函数的作用是找字符串的子串
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<assert.h>
using namespace std;
char* my_strstr(char* str1,char* str2)
{
assert(str1!=NULL);
assert(str2!=NULL);
char* start=(char*)str1;
char* substart=(char*)str2;
char* cp=(char*)str1;
while(*cp)
{
start=cp;
while(*start!='\0'&&*substart!='\0'&&*start==*substart)
{
start++;
substart++;
}
if(*substart=='\0')
return cp;
substart=(char*)str2;
cp++;
}
return NULL;
}
int main()
{
char str1[]="abbbcdefg";
char str2[]="bbcd";
cout<<my_strstr(str1,str2)<<endl;
return 0;
}
首先,根据strstr函数的实现方法得知函数需要传进去的参数是两个字符串,而且这两个字符串都是不可更改的,这样,我们可以利用const来修饰;而且函数返回的也是一个字符串,那么返回值类型也可以确定,这样,我们可以写出这样一个函数的定义:char* my_strstr(const char* dest,const char* src){}。其中,dest指向的是目标字符串,也就是你需要比较的字符串,src指向的是源字符串,也就是用来被比较的字符串。找不到就可以返回一个空指针。
实现的思路也是比较简单的,你可以建立两个指针,通过遍历的方式逐个访问字符串,并对这两个指针一一比较。
举例说明:给上俩个字符串:
str1:abcdefg
str2:bcd
建立两个指针:char *start=str1; char *substart=str2;
此时,start指向字符a,而substart指向字符b,对start和substart两个指针解引用并进行比较,判断是否相等,即*start=*substart;若是两个相等,则两个指针都向后移动一位,再解引用进行判断;若是两个不相等,那么start向后移动一位,substart则将会重新指向str2的起始位置,两个再次进行比较。重复这个过程,直到两个字符串其中一个或者是两个都遇到‘\0’,遍历结束。那么在这里你就可以采用循环的方法来做;循环的判断条件就是(start!='\0' && substart!='\0' && *start==*substart)。
如果到这里你觉得这个函数就算实现成功的话,那你可就掉到坑里去了。我再举个例子吧:
str1:abbbcdefg
str2:bbcd
这里你继续采用上面的方式做,你会得到不一样的结果。
指针判断,当start指向str1中的第一个b时,substart指向str2中的第一个b,两个相等,再往后面遍历,当start指向第三个b的时候,substart指向c,两个不相等,那么此时substart会返回并指向str2中的第一个b。
注意,此时start指向的还是str1中的第三个b,start并没有发生移动,再采用如上的方式比较,从str1的第三个b开始,你再也找不到与str2相同的,那么函数会返回一个 空,可是显然第一个字符串中包含你需要的查找的字符串。这样,我们就需要通过某种方法来解决这个问题。
解决方法其实也是比较简单的:当两个字符串比较的结果不相等时,我们知道substart,就是指向第二个字符串的指针是返回到str2这个字符串的起始位置的,而start这个指针并没有发生任何的变动。再次比较也只能从这个位置继续向后比较,那么中间肯定就会有一些字符是没有办法比较的。所以,当两个字符比较不相等时,start这个指针也需要向前返回,不过它回到的不是起始位置了,而是起始位置的下一个位置,这样就可以避免重复而无用的比较。所以,我们需要在创建一个指针cp用来保存起始位置,并让start返回到起始位置的下一个位置。(此处为从别人博客摘抄的,感觉写的特比妙)
6.实现memcpy
mecmpy是内存的拷贝函数
这个函数的原型是 void* mecmpy(void* destination,const void* source,size_t num);函数mecmpy从source 的位置开始向后复制num个字节的数据到destination的内存位置。注意这个函数在遇到'\0'是不会停下来的。如果source和destination有任何的重叠,复制的结果都是未定义的。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
void* my_memcpy(void* dst,void* src,size_t count)
{
void* ret=dst;
while(count--)#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
void* my_memcpy(void* dst,void* src,size_t count)
{
void* ret=dst;
while(count--)
{
*(char* )dst=*(char* )src;
dst=(char*)dst+1;
src=(char*)src+1;
}
return ret;
}
int main()
{
float arr1[]={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0};
float arr2[10];
int len=sizeof(arr1)/sizeof(arr1[0]);
my_memcpy(arr2,arr1,len);
return 0;
}
{
*(char* )dst=*(char* )src;
dst=(char*)dst+1;
src=(char*)src+1;
}
return ret;
}
int main()
{
float arr1[]={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0};
float arr2[10];
int len=sizeof(arr1)/sizeof(arr1[0]);
my_memcpy(arr2,arr1,len);
return 0;
}
https://blog.csdn.net/Hanani_Jia/article/details/78992428这篇文章把mecmpy写得特别好。
7.实现memmove
此函数和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的,如果源空间和目标空间出现重叠,就得使用memmove函数处理
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
void* memove(void* dst,const void* src,size_t count)
{
void* ret=dst;
if(dst<=src||(char*)dst>=((char*)src+count))
{
while(count--)
{
*(char *)dst=*(char *)src;
dst=(char*)dst+1;
src=(char*)src+1;
}
}
else
{
dst=(char*)dst+count-1;
src=(char*)src+count-1;
while(count--)
{
*(char*)dst=*(char*)src;
dst=(char*)dst-1;
src=(char*)src-1;
}
}
return ret;
}
int main()
{
char str1[]="hello";
char str2[]="world";
int len=strlen(str1);
memmove(str1,str2,len);
cout<<memove(str1,str2,len)<<endl;
return 0;
}
复制的是一个内存。