根据《出现频率最高的笔试题》cphj(原作),及众多的网友的观点。本人做了以下总结: 大多数人都同意以下这个写法:只是个人风格有些不同而已。 char *strcpy(char* dest, const char* src) { assert(NULL != dest); assert(NULL != src);
char *tmp = dest; while('\0' != (*tmp++=*src++)) //因为*tmp不是布尔值所以有必要比较
; return(dest); }
而根据MS中的定义如下: (%VC%/vc7/crt/src/intel/strcat.asm) page ;*** ;char *strcpy(dst, src) - copy one string over another ; ;Purpose: ; Copies the string src into the spot specified by ; dest; assumes enough room. ; ; Algorithm: ; char * strcpy (char * dst, char * src) ; { ; char * cp = dst; ; ; while( *cp++ = *src++ ) ; ; /* Copy src over dst */ ; return( dst ); ; } ; ;Entry: ; char * dst - string over which "src" is to be copied ; const char * src - string to be copied over "dst" ; ;Exit: ; The address of "dst" in EAX ; ;Uses: ; EAX, ECX ; ;Exceptions: ;**********************************************************************
1.没有检查输入的两个指针是否有效。 2.没有检查两个字符串是否以NULL结尾。 3.没有检查目标指针的空间是否大于等于原字符串的空间。
所以这些条件都需要调用者去完成。 看下面程序: //拷贝字符串"abcd" int nLen_Src = 0; int nLen_Dest = 0; char szTemp[] = "1234567890"; char szSrc[] = {'a', 'b', 'c', 'd'}; //正确的用法是在加个'\0' char szDest[2]; //char szDest[5] = {0};栈中分配空间的最小 //边界是4字节,所以szDest数组的大小为1、2、 //3、4下面的结果都是一样的。 nLen_Src = strlen(szSrc); nLen_Dest = strlen(szDest); strcpy(szDest, szSrc);
结果是:nLen_Src = 14, nLen_Dest = 18; szDest = "abcd1234567890", szSrc = "1234567890"; szTemp = "567890"; 数组指针越界导致堆栈中其他变量内容被改变。所以在使用strcpy时要注意以下几点: 1。用数组在栈中分配的字符串空间时,其大小必须比要装入的字符串长 度多一个,以存储结尾的NULL字符(用{0}和'\0'表示),并且要马上 初始化。 2。目标字符串的空间必须大于等于原字符串的空间,否则建议使用 strncpy()或WINAPI的lpstrcpyn() 3。注意在使用LPSTR lstrcpyn(LPTSTR lpString1, LPCTSTR lpString2, int iMaxLength)时,其中的iMaxLength是要拷贝的字符 串长度加1,因为它自动将lpString1的最后一个字符设定为NULL。这 就避免了字符串指针越界了。 4。使用new分配的空间也要及时的初始化。使用memset()或 ZeroMemory()。
--------相关资料可以参考<<高质量C++编程指南>>(林锐博士)

|