`
webcenterol
  • 浏览: 914241 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-1610611985 1107304683 0 0 159 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:新宋体; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@新宋体"; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin-top:0cm; margin-right:0cm; margin-bottom:10.0pt; margin-left:0cm; line-height:115%; mso-pagination:widow-orphan; font-size:12.0pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-fareast-language:EN-US; mso-bidi-language:EN-US;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

原文: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));

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));

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的汇编代码前。。。。哪想的到原来这么简单

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics