strcpy関数の実装の詳細

1592 ワード

私たちは面接の時、ライブラリ関数を呼び出さずにstrcpy関数を実現するという問題によく遭遇します.私たちはこれが簡単だと思いますが、中には注意しなければならない問題があります.
strcpy()関数はc言語のコピー文字列のライブラリ関数であり、実装コードは以下の通りである.
char *strcpy(char *strDest,const char *strSrc)
{
    if((strDest==NULL)||(strSrc==NULL))
    return NULL;
    char *strDestCopy=strDest;
    while((*strDest++==*strSrc++)!='\0');
    return strDestCopy;
}

1.const修飾子、ソース文字列パラメータをconstで修飾し、元の文字列が修正されないようにします.
2.空のポインタをチェックすると、ソースポインタも宛先ポインタも空のポインタが発生する可能性がありますので、チェックします
3.ソース文字列の末尾の0もコピーされます
4.なぜchar*に戻るのですか?
答え:strDestの元の値を返して、関数がチェーン式をサポートできるようにします.
チェーン式の形式は次のとおりです.
int i=strlen(strcpy(strA,strB))

5.strDestとstrSrcメモリの重複を考慮すると、strcpy関数はどのように実現されますか?(たとえば、次のサンプルが実行されると、プログラムがクラッシュします)
char str[10]="abc";  
strcpy(str+1,str);

メモリのオーバーラップを考慮したmy_を次に示します.strcpy関数の実装
char * strcpy(char *dst,const char *src)
{
    assert(dst != NULL && src != NULL);

    char *ret = dst;

    my_memcpy(dst, src, strlen(src)+1);

    return ret;
}

C関数memcpyはメモリオーバーラップ検出機能を備えており、以下memcpyの実現my_を示す.memcpy.
char *my_memcpy(char *dst, const char* src, int cnt)
{
    assert(dst != NULL && src != NULL);

    char *ret = dst; 

    if (dst >= src && dst <= src+cnt-1) //    ,        
    {
        dst = dst+cnt-1;
        src = src+cnt-1;
        while (cnt--)
            *dst-- = *src--;
    }
    else    //    ,        
    {
        while (cnt--)
            *dst++ = *src++;
    }
    
    return ret;
}