一、模拟实现strlen
1.使用计数器实现
int my_strlen(char *p)
{
int count = 0;
while (*p != '\0')
{
count++;
*p++;
}
return count;
}
2.使用递归
int my_strlen(char *p)
{
while (*p!='\0')
{
return 1 + my_strlen(p + 1);
}
return 0;
}
3.使用指针-指针
首先在这里我们要知道:指向同一数组的两个指针相减,是两个指针之间的元素个数,元素个数是由这两个指针类型决定的
int my_strlen(char *p)
{
char *s = p;
while (*p != '\0')
{
*p++;
}
return p - s;
}
int main()
{
char *p= "abcd";
int ret = my_strlen(p);
printf("%d\n", ret);
system("pause");
return 0;
}
二、模拟实现strcpy(字符串拷贝)
char *my_strcpy(char *dest, const char *src) //包括'\0' 只会拷贝而不会修改,用const修改
{
char *ret = dest;
assert(dest);
assert(src);
while (*dest = *src)
{
*dest++;
*src++;
}
return ret;
}
int main()
{
const char *str = "abcdefg";
char buf[64];
int ret=my_strcpy(buf, str);
printf("string=%s\n", ret);
system("pause");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6ae4dc3c2987d0a33cb70f808f1d2096.png)
三、模拟实现strcat(字符串拼接,覆盖前一个的'\0')
在一定程度上也是拷贝,现将指针指向str字符串的最后,然后在进行拷贝
函数原型:extern char *strcat(char *dest, const char *src)
函数功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。
char *my_strcat(char *dest,const char *src) //拼接在一定程度上也是拷贝,因为src不会被修改用const修饰
{
assert(dest);
assert(src);
char *ret = dest;
while (*dest)
{
dest++;
}
while (*dest = *src)
{
dest++;
src++;
}
return ret;
}
int main()
{
char str[64] = "1234";
char buf[64] = "abcd";
my_strcat(str, buf);
printf("string=%s\n", str);
system("pause");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/38f5646c78aca07dbde1138e278abdb8.png)
四、模拟实现strstr
函数原型:char *strstr( const char *string, const char *strCharSet );
函数功能:strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。
char *my_strstr(const char *str, const char *sub_str)
{
assert(str);
assert(sub_str);
char *p = (char*)str;
char *q = (char*)sub_str;
char *np = NULL;
while (*p) //若p字符串已经为0,则未找到,直接退出
{
np = p;
q = sub_str;
while (*np && *q && *np == *q)
{
np++;
q++;
}
if (*q == '\0') //说明已经找到子串
{
return p;
}
if (*np == '\0') //说明没有找到
{
break;
}
p++; //说明是因为np!=q 所以p++接着找
}
return NULL;
}
int main()
{
char arr[64] = "1234abc455abcdefd";
char arr1[64] = "abcd";
printf("string=%s\n", my_strstr(arr, arr1));
system("pause");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/3d593ea955ff8d934e9070c958b14b72.png)
五、模拟实现strcmp(字符串的比较)
原型:extern int strcmp(const char *s1,const char *s2)
matlab中函数,strcmp(s1,s2) 判断两个字符串s1和s2是否相同,相同返回true ,不同返回false
字符串的比较是根据ASCII编码来进行比较的
#include<stdio.h>
#include<stdlib.h>
int strcmp(const char *src, const char *dst)
{
int res = 0;
int ret = 0;
while (!(ret = *(unsigned*)src - *(unsigned*)dst) && *src) //若两个字符相等,那么相减为0(假),取反就为真,保证可以进行比较
{
src++;
dst++;
}
if (ret > 0) //若ret>0,说明str1>str2
{
res = 1;
}
else if (ret<0) //若ret<0,说明str1<str2
{
res = -1;
}
else //str1=str2
{
res = 0;
}
return (res);
}
int main()
{
const char *str1 = "abcdefg";
const char *str2 = "abcdh";
printf("%d\n", strcmp(str1, str2));
system("pause");
return 0;
}
运行结果:
六、模拟实现memcpy(与类型无关)
按字节拷 与strcpy不同的是他对任意类型都可进行拷贝,而strcpy只能对字符串进行拷贝
头文件:#include<string.h>
函数原型:void *memcpy(void *dest, const void *src, size_t n);
函数功能:memcpy指的是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
void *my_memcpy(void *dst, const void *src,int count)
{
assert(dst);
assert(src);
char *_dst =(char *) dst;
char *_src = (char *)src;
while (count--)
{
*_dst = *_src;
_dst++;
_src++;
}
return dst;
}
int main()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int b[10];
my_memcpy(b, a, sizeof(a));
system("pause");
return 0;
}
int main()
{
/*int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int b[10];*/
char str[10] = "abcd";
char str1[10];
my_memcpy(str1, str, strlen(str)+1); // +'\0'
七、模拟实现memmove(考虑内存重叠问题)
函数功能:memmove用于从src拷贝count个字节到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。
头文件:#include<string.h>
原型:void *memmove( void* dest, const void* src, size_t count );
这幅图里面,1,2,3,4都是从左往右拷,不存在内存覆盖的问题,而6是不错误的,那么我们就来考虑5,我们看到5是要考虑内存覆盖的,所以我们对此进行从右向左拷 ,使两个指针都指向各自最后的位置,然后进行拷贝,代码如下:
void *my_memmove(void *dst, const void *src,int count)
{
assert(dst);
assert(src);
char *_dst =(char *) dst;
char *_src = (char *)src;
if (_dst>_src && _dst < _src + count) //从右向左
{
_dst += count-1; //指向最后一个
_src += count-1;
while (count--) //从左往右依次拷
{
*_dst = *_src;
_dst--;
_src--;
}
}
else //从左往右
{
while (count--)
{
*_dst = *_src;
_dst++;
_src++;
}
}
return dst;
}
int main()
{
char str[10] = "abcd";
my_memmove(str+1, str, strlen(str)+1); // +'\0'
printf("%s\n", str);
system("pause");
return 0;
}
运行结果:
八、模拟实现strchr
函数原型:extern char *strchr(char *str,char character)
头文件:#include <string.h>
参数说明:str为一个字符串的指针,character为一个待查找字符。
函数功能:从字符串str中寻找字符character第一次出现的位置。
返回说明:返回指向第一次出现字符character位置的指针,如果没找到则返回NULL。
其它说明:还有一种格式char *strchr( const char *string, int c ),这里字符串是以int型给出的。
这里注释掉的那行代码是用来实现strrchr,从后往前找
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *my_strchr(const char *str, char c)
{
//str = strlen(str)+str-1;
if (str == NULL)
{
return NULL;
}
while (*str)
{
if (*str == c)
{
return (char*)str;
}
str--;
}
return NULL;
}
int main()
{
char *str = "hi i am code!";
char character = 'a';
printf("%s\n", my_strchr(str, character));
system("pause");
return 0;
}
运行结果: