当前位置: 技术问答>linux和unix
while( * strDest++ = * strSrc++ )是否可行??为什么??
来源: 互联网 发布时间:2016-04-05
本文导语: char * strcpy( char * strDest, const char * strSrc ) { char * address; assert( ( strDest != NULL ) && ( strSrc != NULL ) ); address = strDest; while( ( * strDest++ = * strSrc++ ) != '' ); ...
char * strcpy( char * strDest, const char * strSrc )
{
char * address;
assert( ( strDest != NULL ) && ( strSrc != NULL ) );
address = strDest;
while( ( * strDest++ = * strSrc++ ) != '' );
return address;
}
/*************************************************************/
char * strcpy( char * strDest, const char * strSrc )
{
char * address;
assert( ( strDest != NULL ) && ( strSrc != NULL ) );
address = strDest;
while( * strDest++ = * strSrc++ );
return address;
}
{
char * address;
assert( ( strDest != NULL ) && ( strSrc != NULL ) );
address = strDest;
while( ( * strDest++ = * strSrc++ ) != '' );
return address;
}
/*************************************************************/
char * strcpy( char * strDest, const char * strSrc )
{
char * address;
assert( ( strDest != NULL ) && ( strSrc != NULL ) );
address = strDest;
while( * strDest++ = * strSrc++ );
return address;
}
|
A:while( ( * strDest++ = * strSrc++ ) != '' );
B:while( * strDest++ = * strSrc++ );
这两种写发都可行,且效率是一样的!
理由如下:
众所周知,在32位系统中,C语言字符变量占一个字节,字符串在内存中以字符‘’为结束标志,而字符‘’的ASCII值就等于0。
在C语言中的条件判断,当值为0,为假,非0为真。
语句A的意思是:取strSrc中的一字节内容,赋给strDest,再比较*strDest与‘’是否相等,然后strSrc加一,strDest加一。
语句B的意思是:取strSrc中的一字节内容,赋给strDest,再根据*strDest的值,判断条件的真假,如果*strDest等于0为假,否则为真。
然后strSrc加一,strDest加一。
0040103E mov ecx,dword ptr [ebp+8] //取指针strDest
00401041 mov edx,dword ptr [ebp+0Ch] //取指针strSrc
00401044 mov al,byte ptr [edx] //*strSrc暂存至ecx的低16位(al)
00401046 mov byte ptr [ecx],al //*strDest = *strSrc
00401048 mov ecx,dword ptr [ebp+8] //strDest暂存至ecx
0040104B movsx edx,byte ptr [ecx] //*strDest暂存至edx
0040104E mov eax,dword ptr [ebp+8] //strDest暂存至eax
00401051 add eax,1 //strDest++
00401054 mov dword ptr [ebp+8],eax //把改变后的strDest放回先前的位置
00401057 mov ecx,dword ptr [ebp+0Ch] //取指针strSrc
0040105A add ecx,1 //strSrc++
0040105D mov dword ptr [ebp+0Ch],ecx //把改变后的strSrc放回先前的位置
00401060 test edx,edx //测试寄存器edx是否为空(edx其实等于*strDest)
00401062 je MyStrcpy+46h (00401066) //不为0,退出循环
00401064 jmp MyStrcpy+1Eh (0040103e) //否则跳到0040103e处,继续循环
B:while( * strDest++ = * strSrc++ );
这两种写发都可行,且效率是一样的!
理由如下:
众所周知,在32位系统中,C语言字符变量占一个字节,字符串在内存中以字符‘’为结束标志,而字符‘’的ASCII值就等于0。
在C语言中的条件判断,当值为0,为假,非0为真。
语句A的意思是:取strSrc中的一字节内容,赋给strDest,再比较*strDest与‘’是否相等,然后strSrc加一,strDest加一。
语句B的意思是:取strSrc中的一字节内容,赋给strDest,再根据*strDest的值,判断条件的真假,如果*strDest等于0为假,否则为真。
然后strSrc加一,strDest加一。
0040103E mov ecx,dword ptr [ebp+8] //取指针strDest
00401041 mov edx,dword ptr [ebp+0Ch] //取指针strSrc
00401044 mov al,byte ptr [edx] //*strSrc暂存至ecx的低16位(al)
00401046 mov byte ptr [ecx],al //*strDest = *strSrc
00401048 mov ecx,dword ptr [ebp+8] //strDest暂存至ecx
0040104B movsx edx,byte ptr [ecx] //*strDest暂存至edx
0040104E mov eax,dword ptr [ebp+8] //strDest暂存至eax
00401051 add eax,1 //strDest++
00401054 mov dword ptr [ebp+8],eax //把改变后的strDest放回先前的位置
00401057 mov ecx,dword ptr [ebp+0Ch] //取指针strSrc
0040105A add ecx,1 //strSrc++
0040105D mov dword ptr [ebp+0Ch],ecx //把改变后的strSrc放回先前的位置
00401060 test edx,edx //测试寄存器edx是否为空(edx其实等于*strDest)
00401062 je MyStrcpy+46h (00401066) //不为0,退出循环
00401064 jmp MyStrcpy+1Eh (0040103e) //否则跳到0040103e处,继续循环
|
while( ( * strDest++ = * strSrc++ ) != '' );
while( * strDest++ = * strSrc++ );
等效,while(0)和while ('' != 0)在C里是一样的。
|
没看出你的while('' != 0)是针对哪一句说的。
我只看到结束时是while('' != '')和while('')
我只看到结束时是while('' != '')和while('')
|
楼主问的问题到底是什么?编译器没有漏洞。while(0)和while ('' != 0)在C里是一样的。