面試中常見的字串庫函式程式設計
阿新 • • 發佈:2018-12-25
下面對一些常見的關於字元的庫函式進行實現,這些也是通常面試中所問的一些問題,需要注意的是有些看起來很簡單,但是一定要考慮一些邊界條件,否則很容易出錯.
strcpy實現
char* strcpy(char* dst,const char* src){
if(dst== nullptr||src== nullptr) //注意邊界條件
return nullptr;
char* pdst =dst;
const char* psrc = src;
while(*psrc!='\0') { //這裡不能寫成psrc!='\0'
*pdst++ = *psrc++;
}
*pdst = '\0' ; //注意結尾
return dst;
}
strncpy實現
char* strncpy(char* dst,const char* src,size_t count) {
if(dst== nullptr||src== nullptr||count<=0)
return dst;
char* pdst =dst;
const char* psrc = src;
while(count--&&*psrc!='\0') {
*pdst++ = *psrc++;
}
*pdst = '\0' ; //注意
return dst;
}
上述的兩個關於拷貝的函式都有問題–其沒有考慮到記憶體的重疊的問題,因此會有下面一個函式作為代替.
memmove實現
void* memmove(void *dst,const void *src,size_t n) {
//判斷合法性
if (dst == NULL || src == NULL)
return NULL;
char* pdst = (char*)dst; //強制轉換成char*
const char* psrc=(const char*)src;
//防止記憶體重疊的處理
if (pdst<psrc) {
for (size_t i = 0;i<n;i++)
*(pdst++)=*(psrc++);
}
else { //從後往前
pdst += n-1;
psrc += n-1;
for (size_t i = 0;i<n;i++)
*(pdst--)=*(psrc--);
}
*pdst='\0';
return dst;
}
strlen實現
最常見的庫函數了,下面是一種實現的方式
size_t mystrlen(const char* src) {
if(src== nullptr) return 0;
size_t count=0;
while(*src!='\0') {
src++;
count++;
}
return count;
}
memset實現
這個函式是非常容易出錯的,因為它是以位元組為單位進行初始化的,因此如果對與int等別的型別進行初始化的時候要非常小心.
//其函式的形式就是標準的庫函式形式
void* mymemset(void* src,int ch,size_t n){ //注意函式的形式
if(src== nullptr)
return src;
char* psrc = (char*)src;
while(n--){
*psrc++ = static_cast<char>(ch);
}
return src;
}
測試
下面對上述的函式進行測試,看出其不同的地方:
#include <iostream>
using namespace std;
char* strcpy(char* dst,const char* src){
if(dst== nullptr||src== nullptr)
return nullptr;
char* pdst =dst;
const char* psrc = src;
while(*psrc!='\0') {
*pdst++ = *psrc++;
}
*pdst = '\0';
return dst;
}
char* strncpy(char* dst,const char* src,size_t count) {
if(dst== nullptr||src== nullptr||count<=0)
return dst;
char* pdst =dst;
const char* psrc = src;
while(count--&&*psrc!='\0') {
*pdst++ = *psrc++;
}
*pdst = '\0';
return dst;
}
void* memmove(void *dst,const void *src,size_t n) {
//判斷合法性
if (dst == NULL || src == NULL)
return NULL;
char* pdst = (char*)dst;
const char* psrc=(const char*)src;
//防止記憶體重疊的處理
if (pdst<psrc) {
for (size_t i = 0;i<n;i++)
*(pdst++)=*(psrc++);
}
else {
pdst += n-1;
psrc += n-1;
for (size_t i = 0;i<n;i++)
*(pdst--)=*(psrc--);
}
*pdst='\0';
return dst;
}
size_t mystrlen(const char* src) {
if(src== nullptr) return 0;
size_t count=0;
while(*src!='\0') {
src++;
count++;
}
return count;
}
void* mymemset(void* src,int ch,size_t n){
if(src== nullptr)
return src;
char* psrc = (char*)src;
while(n--){
*psrc++ = static_cast<char>(ch);
}
return src;
}
int main() {
//兩種情況會不同...有記憶體的重疊
char c1[]="hello,world";
char c2[]="hello,world";
memmove(c2+6,c2+5,5);
strncpy(c1+6,c1+5,5);
cout<<c1<<endl;
cout<<c2<<endl;
////////////////////////
char t[]="12345";
cout<<mystrlen(t)<<endl; //5
cout<<sizeof(t)<<endl; //6 , have '\0'
char* t1 ="12345";
cout<<sizeof(t1)<<endl; //8 ,pointer,64 machine
cout<<mystrlen(t1)<<endl; //5
///////////////////////注意memeset函式的用法
char buf[10];
mymemset(buf,'1',sizeof(buf));
for(int i=0;i<sizeof(buf);i++)
cout<<buf[i]<<" ";
cout<<endl;
int buf1[10];
mymemset(buf1,1,sizeof(buf1));
cout<<sizeof(buf1)<<endl;
for(int i=0;i<sizeof(buf1)/sizeof(int);i++)
cout<<buf1[i]<<" ";
cout<<endl;
return 0;
}
…………to be continue