實現字符串拷貝 內存拷貝函數,考慮內存摺疊的情況
之前面試中面試官讓實現一個內存拷貝函數時,一臉懵逼,只知道有內存拷貝函數,有幾個參數都不記得了,於是面試官讓實現一個字符串拷貝函數,就寫了一下,但是寫完以後面試官說我沒有考慮到內存摺疊的情況,當時真的不知道什麼是內存摺疊,也沒有寫出來。
在這裏總結一下常用的字符串處理函數的實現,以及內存拷貝考慮內存摺疊時的情況:
字符串拷貝內存摺疊:拷貝過程中覆蓋了還未處理的字符。
#include <iostream>
#include <cstring>
using namespace std;
/*
* 內存拷貝,考慮內存摺疊的情況
*/
void *memcpy(void *dest, const void * src, std::size_t n){
if(!dest || !src)
return nullptr;
if(dest == src)
return const_cast<void *>(src);
char *temp = (char *)dest;
const char *s = (char *)src;
if(temp > s && temp < s + n){
temp = temp + n -1;
s = s + n - 1;
while (n--){
*temp-- = *s--;
}
} else{
while (n--)
*temp++ = *s++;
}
return dest;
}
/*
* 字符拷貝,考慮內存摺疊的情況
*/
char *myStrcpy(char *dest,char *src){
if(!dest || !src){
return nullptr;
}
if(dest == src)
return src;
char *temp = dest;
int size = strlen(src) + 1; // size要算上'\0'
if(dest < src || dest > src + size){
while(size--)
*temp++ = *src++;
} else{ // 發生內存摺疊,從後往前複製
temp = temp+size-1;
src = src + size - 1;
while(size--)
*temp-- = *src--;
}
return dest;
}
/*
* 比較兩個字符串
*/
int myStrcomp(const char *str1, const char *str2){
while (*str1 == *str2 && *str1 != '\0'){
++str1;
++str2;
}
return *str1 - *str2;
}
/*
* 連接兩個字符串
*/
char *strcat(char* dest,const char* src){
char* d = dest;
while (*d != '\0')
d++;
while (*src != '\0'){
*d++ = *src++;
}
*d = '\0';
return dest;
}
/*
* 查找str2在str1中的位置以後的字符
*/
char* strstr(char *str1,char *str2){
if(!str1 || !str2)
return nullptr;
char *temp = str1;
if(*str2 == '\0') // str2爲空
return nullptr;
while (*temp != '\0'){
char *a = temp;
char *b = str2;
while (*a != '\0' && *b != '\0' && *a == *b){
++a;
++b;
}
if(*b == '\0')
return temp;
else if(*a == '\0')
return nullptr;
temp++;
}
return nullptr;
}
int main(){
char myName[] = "sunlight";
char substr[] = "lig";
char destChar[20];
memcpy(destChar,myName,strlen(myName)+1);
cout<<"destChar:"<<destChar<<" myName:"<<myName<<endl;
memcpy(myName+2,myName,strlen(myName)+1);// 發生內存摺疊
cout<<"destChar:"<<destChar<<" myName:"<<myName<<endl;
cout<<"compare:"<<myStrcomp(destChar,myName)<<endl;
cout<<"cat destChar and myName:"<<strcat(destChar,myName)<<endl;
cout<<"strstr substr in myName:"<<strstr(myName,substr)<<endl;
return 0;
}