<!--
/* 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的汇编代码前。。。。哪想的到原来这么简单
分享到:
相关推荐
网上参考资料写的memcpy以及strcpy的源码,希望能帮助大家。
memcpy 和strcpy 的区别
用于了解安全函数strcpy_s、strncpy_s、snprintf_s、memcpy_s
常用函数的实现strcpy,memcpy,memmove,strcat,strcmp原型
memset,memcpy,strcpy 的用法,详细区别还有优缺点对比!
本文详细介绍了Memset、Memcpy、Strcpy 的作用及三者的区别,函数原型及使用技巧等。
本篇文章是对strcpy与memcpy的区别进行了详细的分析介绍,需要的朋友参考下
C语言 strcpy和memcpy区别详细介绍 PS:初学算法,开始刷leetcode,Rotate array的预备知识(写的代码Time Limit Exceed难过)于是百度高效算法,本篇作为预备知识。 1、strcpy和strncpy函数 这个不陌生,大一学...
本篇文章是对C++中memset,memcpy,strcpy的区别进行了详细的分析介绍,需要的朋友参考下
void memsetEX(unsigned char *dst,unsigned char val,unsigned char len); void memcpyEX(unsigned char *dst,unsigned char *src,unsigned char len); unsigned char memcmpEX(unsigned char *dst,unsigned char...
。。。
。。。
1. 复制的内容不同 2. 复制的法不同 3. 途不同 1. dest指向的空间要够拷 3. 使strncpy时,确保dest的最后个字符是“\0”
strcmp strcpy strcat strlen 的实现 以及与strncat strncpy strncmp memcpy memcmp 原型分析
函数原型 void *memcpy(void*dest, const void *src, size_t n);...与strcpy相比,memcpy并不是遇到''结束,而是一定会拷贝完n个字节。 memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型
。。。
。。。