模拟实现一些函数(strlen、strcpy、strcat、strstr、strcmp、memcpy、memmove、strchr)

一、模拟实现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 *strcpy(char* dest, const char *src);
头文件:#include < string.h> 和 #include <stdio.h>
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的 地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的 指针

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;
}


三、模拟实现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;
}

四、模拟实现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;
}


五、模拟实现strcmp(字符串的比较)

原型:extern int strcmp(const char *s1,const char *s2)

函数功能:C/C++函数,比较两个字符串
设这两个字符串为str1,str2,
若str1==str2,则返回零;
若str1<str2,则返回负数;
若str1>str2,则返回正数。

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;

}

运行结果:




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值