字符串相關函數及自我實現

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函數字符串分割函數等都可以實現,這裏就不再多說。

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