字符串相关函数及自我实现

strlen
这个函数是求字符串长度的函数,遇到’\0’即停止,返回的类型一个正整数。其传参样式为strlen(str)意思为求字符串str的长度并且返回。自我实现也比较好实现,函数部分代码如下

int My_Strlen(const char* former)
{
	int i =0;
	while(*former!='\0'){
		i++;
		former++;
	}
	return i;
}

strcpy
这个函数为字符串赋值函数,其中需要注意的是’\0’也需要复制,并且要求空间足够大。传参样式为strcpy(str1,str2),意思为将字符串str2复制到str1当中去,当然,str1的长度要足够大,容纳的下str1,而这个长度则是由程序员自身决定,自我实现代码如下

char* My_Strcpy(char* str1,const char* str2)
{
	if(str1==NULL||str2==NULL){
		return 0;
	}
	char* temp=str1;
	while(*str2!='\0'){
		*temp++=*str2++;
	}
	*temp='\0';
	return str1;
}

strcat
这个函数为字符串拼接函数,传参样式如下scrcat(str1,str2),是将str2连接到str1的后面,要注意此时str1已改变,而str2不会改变,实现代码如下

char* My_Strcat(char* str1,char* str2)
{
	if(str1==NULL||str2==NULL){
		return 0;
	}
	while(*str1!='\0'){
		str1++;
	}
	while(*str2!='\0'){
		*str1++=*str2++;
	}
	*str1='\0';
	return str1;
}

strcmp
这个函数为字符串比较函数,顾名思义为比较两个字符串大小的函数,传参样式为strcmp(str1,str2),意为比较str1和str2两个字符串,如果str1大则返回一个大于0的数,相等则返回0,小于str2则返回小于0的数。函数实现如下

int My_Strcmp(char* str1,const char* str2)
{
	if(*str1=='\0'||*str2=='\0'){
		return 0;
	}
	while(*str1!='\0'){
		if(*str1==*str2){
			str1++;
			str2++;
		}
		if(*str2=='\0'&&*str1!='\0'){
			return 1;//str1>str2
		}
		if(*str2=='\0'&&*str1=='\0'){
			return 0;//str1==str2
		}
	}
	return -1;//str1<str22
}

strstr
这个函数为查找字符串中子串的位置,并且返回指向字符串中子串出现的首元素地址的指针。传参样式strstr(str1,str2),这里注意的是,这个函数的自我实现中需要另外的指针来记录寻找位置除此之外,如果没有找到子串,则返回NULL。函数实现如下

char* My_Strstr(char* dest,char*src)
{
	assert(dest!=NULL&&src!=NULL);
	if(*src=='\0'){
		return NULL;
	}
	char* black=dest;//记录当前字符串的位置
	while(*black!='\0'){
		char* red=black;//记录当前字符串查找到的位置
		char* sblack=src;//记录子串查找的位置
		while(*red!='\0'&&*sblack!='\0'&&(*sblack==*red)){//如果相等则继续比较
			sblack++;
			red++;
		}
		if(*sblack=='\0'){//此时子串已结束,说明查找成功
			return black;
		}
		if(*red=='\0'){//此时字符串已结束,说明没有找到
			return NULL;
		}
		black++;//记录的位置+1
	}
	return NULL;//上述大while循环结束,没有找到
}

memcpy
这个函数大家可能没见过,它是拷贝内存的函数,与之前的字符串复制函数不同,这个函数所拷贝的是内存,即无论是什么类型的内存,都可以拷贝。传参样式如下memcpy(dest,src,num_of_size),注意,最后一个参数的单位为字节,比如你要拷贝2个int型的内存中的数据,则num_of_size为8。代码实现如下

void *My_Memcpy(void* dest,const void* src,const size_t size_of_num)
{
	assert(dest!=NULL&&src!=NULL);//断言
  void* temp = dest;//记录dest的首地址
	for(int i=0;i<size_of_num;i++){
		*(char*)dest++=*(char*)src++;//void*是一个特殊的指针,只包含地址,没有内存空间大小,
									//不能++,--,解引用所以要强制转换为char*型,再进行操作
	}
	return temp;
}

memmove
这个函数与上一个函数功能一样,但是唯一不同的是这个函数可以处理缓冲区重叠的问题,即传入的两个参数对应的内存存在重叠问题。传参样式如下memcpy(dest,src,num_of_size)。

void* My_Memmove(void* dest,const void* src,const size_t size_of_num)
{
	assert(dest!=NULL&&src!=NULL);//断言
	char* Dest=(char*)dest;//记录dest当前的地址
	char* Src=(char*)src;//记录src当前的地址
	if(Dest>Src&&Dest<Src+size_of_num){//当存在内存重叠时
		char* temp = Dest+size_of_num-1;//找到Dest的最后一个字节
		Src=Src+size_of_num-1;//找到src的最后一个字节
		for(int i = 0;i<size_of_num;i++){
			*temp--=*Src--;//从后往前复制
		}
		return dest;
	}
	else{//不存在内存重叠时,于My_Memcpy的实现一样
		void* temp = dest;
		for(int i=0;i<size_of_num;i++){
			*(char*)dest++=*(char*)src++;
		}
		return temp;
	}
}

还有一些函数如strncmp函数比较钱N个字符大小,strtok函数字符串分割函数等都可以实现,这里就不再多说。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章