九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

关于strcpy的问题,解释一下为什么VS中标准的方法不用memcpy实现

原文:http://blog.csdn.net/youyouzhishen/archive/2008/11/02/3207836.aspx

#include <cstring>

using namespace std;

inline char* myStrcpy(char* apszDest, char* apszSrc)
{
    memcpy(apszDest, apszSrc, strlen(apszSrc) + 1);
    return apszDest;
}

int _tmain(int argc, _TCHAR* argv[])
{
    char lszSrc[] = "GOD, I'm a test string./n";
    char lszDest[256];

    printf("%s",myStrcpy(lszDest, lszSrc));
    printf("%s",strcpy(lszDest, lszSrc));

    return 0;
}

其实strcpy实现成我上面写的那样一样也可以实现strcpy,并且平均效率似乎要更高。这种错觉来自于debug时看到的strcpy的源代码(K&R中,一般的笔试题也广为通用此源代码)

其实到最近才知道,debug时可以看到strcpy的实现,memcpy一般情况下比strcpy那样的实现效率要高,这是很明显的,哪怕字符数量比较小,memcpy起码也不输给strcpy,但是,事实上,在优化后的release汇编代码就能发现,其实strcpy这样常用的函数(虽然是C Runtime Library的函数),但是编译器实际是做了优化的,这些叫做内部函数(中文版VS2005标准译法),直接就通过strcpy生成了汇编代码,所以实现上就没有必要使用memcpy了,见下面的汇编代码。

printf("%s",myStrcpy(lszDest, lszSrc)); ```asm 00401026 8D 44 24 08      lea         eax,[esp+8]  0040102A A4               movs        byte ptr es:[edi],byte ptr [esi]  0040102B 8D 50 01         lea         edx,[eax+1]  0040102E 8B FF            mov         edi,edi  00401030 8A 08            mov         cl,byte ptr [eax]  00401032 83 C0 01         add         eax,1  00401035 84 C9            test        cl,cl  00401037 75 F7            jne         wmain+30h (401030h)  00401039 2B C2            sub         eax,edx  0040103B 83 C0 01         add         eax,1  0040103E 50               push        eax  0040103F 8D 44 24 0C      lea         eax,[esp+0Ch]  00401043 50               push        eax  00401044 8D 4C 24 2C      lea         ecx,[esp+2Ch]  00401048 51               push        ecx  00401049 E8 26 08 00 00   call        memcpy (401874h)  0040104E 8B 35 A0 20 40 00 mov         esi,dword ptr [__imp__printf (4020A0h)]  00401054 8D 54 24 30      lea         edx,[esp+30h]  00401058 52               push        edx  00401059 68 10 21 40 00   push        offset string "%s" (402110h)  0040105E FF D6           call        esi  00401060 83 C4 14         add         esp,14h  ```

printf("%s",strcpy(lszDest, lszSrc)); ```asm 00401063 33 C0            xor         eax,eax  00401065 8A 4C 04 08      mov         cl,byte ptr [esp+eax+8]  00401069 88 4C 04 24      mov         byte ptr [esp+eax+24h],cl  0040106D 83 C0 01         add         eax,1  00401070 84 C9            test        cl,cl  00401072 75 F1            jne         wmain+65h (401065h)  00401074 8D 44 24 24      lea         eax,[esp+24h]  00401078 50               push        eax  00401079 68 10 21 40 00   push        offset string "%s" (402110h)  0040107E FF D6           call        esi  ```

没有见过strcpy的汇编代码前。。。。哪想的到原来这么简单

分类:  C++ 
标签:  C++  memcpy  strcpy 

Posted By 九天雁翎 at 九天雁翎的博客 on 2008年11月09日

前一篇: 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 用C++/lua/python/bash的四重实现(1) f(x) = 2f(x-1) + x^2 后一篇: 一天一个C Run-Time Library 函数 (9) atexit