找回密码
 注册
搜索
查看: 1378|回复: 8

[讨论] strcpy代码请教

[复制链接]
发表于 2006-11-15 09:36:29 | 显示全部楼层 |阅读模式
char *strcpy(char*strDest, const char*strSrc)
{
char *address = strDest;
while ((*strDest++ = *strSrc++) != NULL)
continue;
   return address;
}
请问这条 while ((*strDest++ = *strSrc++) != NULL)的执行顺序是怎样的?
是先strDest=strSrc,再strDest++和strSrc++,最后判断 赋值成功否!=NULL,是这样吗?
而且const char*strSrc,是const类型怎么可以改变地址呢?
最后的判断会==NULL吗?
我在vc中试循环是可以结束的
[em03][em03]
发表于 2006-11-15 17:42:06 | 显示全部楼层
我来说说我的看法:
应该是先判断 赋值成功否!=NULL,
然后strDest=strSrc,
最后strDest++和strSrc++,

const char * strSrc;  const是修饰指针所指向的变量,指向的内容是不能改变。
const在右边才是修饰指针。如char *strSrc const;这样strSrc就不能++

可以访问我的BLOG看相关内容:http://hecrics.52rd.net
点评回复

使用道具 举报

 楼主| 发表于 2006-11-16 12:15:51 | 显示全部楼层
楼上的和我一样是菜鸟
点评回复

使用道具 举报

发表于 2006-11-16 18:46:29 | 显示全部楼层
++运算符作为后缀表示表达式求值完成后自增,也就是先对strDest指针解引用取得它的值,
然后指针后移一个单位,至于是先对*strDest++还是*strSrc++求值,这个不同编译器可以
有不同定义,因为c语言没有规定赋值运算符的求值顺序,c语言中规定了求值顺序的运算符
只有4个: &&  ||  :?  ,
点评回复

使用道具 举报

发表于 2006-11-18 19:57:20 | 显示全部楼层
先赋值,然后修改指针变量,再判断值是否为结束标志符,如果是则退出,否则继续[br]<p align=right><font color=red>+1 RD币</font></p>
点评回复

使用道具 举报

发表于 2006-12-2 09:48:56 | 显示全部楼层
while ((*strDest++ = *strSrc++) != NULL);
1)*strDest = *strSrc;
2)*strDest ==NULL
3)strDest++;strSrc++;
先赋值,然后判断值是否为结束标志符,再修改指针变量
如果是则退出,否则,继续
------------------------------------------------------------------------
如果按楼上zdchl的说法,NULL是不会copy的。
等下贴段汇编上来看看权威的答案。

const加在参数里面只是表示这个意思
比如
strcpy(pDest,"52rd.com");
在执行完以后,pDest不会变化
如果没有const修饰,
在执行完以后,pDest会变化的。
等下贴个测试的例子来验证一下。
点评回复

使用道具 举报

发表于 2006-12-2 11:17:45 | 显示全部楼层
#include "stdafx.h"
char *strcpy( char*strDest,const  char*strSrc)
{[/COLOR]
004113A0  push        ebp  
004113A1  mov         ebp,esp
004113A3  sub         esp,0D0h
004113A9  push        ebx  
004113AA  push        esi  
004113AB  push        edi  
004113AC  lea         edi,[ebp-0D0h]
004113B2  mov         ecx,34h
004113B7  mov         eax,0CCCCCCCCh
004113BC  rep stos    dword ptr es:[edi]
char *address = strDest;[/COLOR]
004113BE  mov         eax,dword ptr [strDest] ;eax里面存放strDest的地址
004113C1  mov         dword ptr [address],eax ;adress里面存放eax,也就是strDest的地址
while ((*strDest++ = *strSrc++) != NULL);[/COLOR]
004113C4  mov         eax,dword ptr [strDest] ;eax里面是strDest的地址
004113C7  mov         ecx,dword ptr [strSrc]  ;ecx里面是strSrc的地址
004113CA  mov         dl,byte ptr [ecx]       ;把ecx指向的字节给dl,dl里面就是*strSrc
004113CC  mov         byte ptr [eax],dl       ;dl放到eax指向的字节,那就是完成了*strDest=*strSrc
004113CE  mov         eax,dword ptr [strDest] ;eax里面是strDest的地址
004113D1  movsx       ecx,byte ptr [eax]      ;ecx里面是eax指向的字节,也就是*strDest了。
004113D4  mov         edx,dword ptr [strDest] ;edx里面是strDest的地址
004113D7  add         edx,1                   ;edx+1,
004113DA  mov         dword ptr [strDest],edx ;edx传回到strDest,就是strDest++;
004113DD  mov         eax,dword ptr [strSrc]  ;eax里面是strSrc的地址
004113E0  add         eax,1                   ;eax+1
004113E3  mov         dword ptr [strSrc],eax  ;eax传回到strSrc,就是strSrc++;
--------------------------------------------------------------------------------
004113E6  test        ecx,ecx                 ;测试ecx,看看前面ecx里面放的是什么?(自加前的*strDest)
004113E8  je          strcpy+56h (4113F6h)    ;ecx=0,跳到后面13F6H(会给某个临时变量赋0)
004113EA  mov         dword ptr [ebp-0D0h],1  ;ecx!=0,给这个临时变量赋1
004113F4  jmp         strcpy+60h (411400h)    ;跳到后面1400H(看看这个临时变量是不是0)
004113F6  mov         dword ptr [ebp-0D0h],0  ;前面(13E8)跳过来的,给这个临时变量赋0
00411400  cmp         dword ptr [ebp-0D0h],0  ;前面(13F4)跳过来的,看看这个临时变量是不是0
00411407  je          strcpy+6Bh (41140Bh)    ;这个临时变量0,跳出循环,
00411409  jmp         strcpy+24h (4113C4h)    ;这个临时变量不是0,跳到上面while循环开始的地方。
--------------------------------------------------------------------------------
;这段好啰嗦,可能是debug版本的原因吧,Release版本应该不会这样吧!
   return address;[/COLOR]
0041140B  mov         eax,dword ptr [address]
}
点评回复

使用道具 举报

 楼主| 发表于 2006-12-11 10:08:16 | 显示全部楼层
谢谢楼上的高手
点评回复

使用道具 举报

发表于 2006-12-18 21:48:14 | 显示全部楼层
to shinedream,
最好是先按照C STANDARD来讲,毕竟不同平台不同编译器产生的汇编代码是不同的。
哈,幸亏你没在comp.lang.c里发这种信,要不然会被那帮老外BS死的。
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-12-23 22:31 , Processed in 0.045929 second(s), 16 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表