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