面试中常见的字符串库函数编程

下面对一些常见的关于字符的库函数进行实现,这些也是通常面试中所问的一些问题,需要注意的是有些看起来很简单,但是一定要考虑一些边界条件,否则很容易出错.

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 (pdstfor (size_t i = 0;ielse {                    //从后往前
        pdst += n-1;
        psrc += n-1;
        for (size_t i = 0;i'\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 
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 (pdstfor (size_t i = 0;ielse {
        pdst += n-1;
        psrc += n-1;
        for (size_t i = 0;i'\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<cout<////////////////////////
    char t[]="12345";
    cout<//5
    cout<<sizeof(t)<//6 , have '\0'
    char* t1 ="12345";
    cout<<sizeof(t1)<//8 ,pointer,64 machine
    cout<//5
    ///////////////////////注意memeset函数的用法
    char buf[10];
    mymemset(buf,'1',sizeof(buf));
    for(int i=0;i<sizeof(buf);i++)
        cout<" ";
    cout<int buf1[10];
    mymemset(buf1,1,sizeof(buf1));
    cout<<sizeof(buf1)<for(int i=0;i<sizeof(buf1)/sizeof(int);i++)
        cout<" ";
    cout<return 0;
}

…………to be continue

你可能感兴趣的:(Interview)