Question:
It is known that the prototype of the strcpy function is:
Char * strcpy (char * strdest, const char * strsrc );
1. Implement the strcpy function without calling the library function.
2. Explain why char * is returned *.
Explanation:
1. Implementation Code of strcpy
char * strcpy(char * strDest,const char * strSrc) { if ((strDest==NULL)||(strSrc==NULL)) //[1] throw "Invalid argument(s)"; //[2] char * strDestCopy=strDest; //[3] while ((*strDest++=*strSrc++)!='\0'); //[4] return strDestCopy; }
Incorrect practice:
[1]
(A) if the pointer is not checked, it means that the respondent does not pay attention to the robustness of the Code.
(B) used to check the pointer validity ((! Strdest) | (! Strsrc) or (! (Strdest & strsrc). It indicates that the respondent has no deep understanding of implicit conversions of types in C language. In this example, char * is converted to bool, that is, implicit type conversion. Although this function is flexible, it is more likely to increase the error probability and increase the maintenance cost. Therefore, C ++ adds the bool, true, and false keywords to provide a safer conditional expression.
(C) Use (strdest = 0) | (strsrc = 0) to check the pointer validity. This means that the respondent does not know the benefit of using constants. Directly Using a literal constant (such as 0 in this example) reduces the maintainability of the program. 0 is simple, but there may be a lot of pointer checks in the program. In case of PEN mistakes, the compiler cannot find that the generated program contains logical errors and it is difficult to eliminate them. If null is used to replace 0, the compiler will check if a spelling error occurs.
[2]
(A) return new string ("invalid argument (s)";, indicating that the respondent does not know the purpose of the returned value, and is not cautious about memory leakage. Returning the memory allocated in the function body from the function is very dangerous. It throws the obligation to release the memory to an uninformed caller. In most cases, the caller will not release the memory, which leads to memory leakage.
(B) Return 0;, indicating that the respondent did not master the exception mechanism. The caller may forget to check the return value, and the caller may not be able to check the return value (see the chain expression below ). If you want the return value to shoulder the dual function of returning the correct value and abnormal value, the result is often invalid in both functions. The return value should be replaced by throwing an exception, which can reduce the burden on the caller, prevent errors from being ignored, and enhance the maintainability of the program.
[3]
(A) if you forget to save the original strdest value, it means that the answer provider's logic is not strict.
[4]
(A) cyclically write it as while (* strdest ++ = * strsrc ++);, same as [1] (B ).
(B) cyclically write while (* strsrc! = '\ 0') * strdest ++ = * strsrc ++;, indicating that the respondent does not check the boundary condition effectively. After the loop body ends, '\ 0' is not correctly added to the end of the strdest string '.
2. Return the original strdest value to enable the function to support chained expressions, increasing the "added value" of the function ". Functions of the same function are naturally more ideal if they can reasonably improve availability.
The form of a chained expression is as follows:
Int ilength = strlen (strcpy (stra, strb ));
Another example:
Char * stra = strcpy (New char [10], strb );
The original strsrc value is returned incorrectly. First, the source string must be known and it does not make sense to return it. Second, the expression in the second example cannot be supported. Third, to protect the source string, the const uses const to limit the content referred to by strsrc and returns const char * as char *. If the type is different, an error is returned during compilation.
#include <stdio.h> //#include <string.h>char *strcpy(char *a,char *b){ if (NULL==a||NULL==b) return NULL; char *temp=a; while ((*a++=*b++)!='\0'); return temp;}//int strlen(char *a)//{// int len=0;// for (len=0; *a!='\0'; a++)// len++;// return len; //}int strlen(char *s){ char *p=s; while (*s!='\0') s++; return s-p;}/*int strlen (char *s){ int len=0; for (int i=0; ; i++) { if (s[i]=='\0') break; len++; } return len;}*/void foo(void) { char string[10],str1[10]; int j; for(j=0;j<9;j++) { str1[j]='a'; } str1[j]='\0';strcpy(string,str1);int len=strlen(string); printf("%s",string); printf ("\n%d",len); }int main(){ foo(); char ch[8]="0123456"; //char ch[8]={'0','1','2','3','4','5','6','\0',}; printf("\n%d\n",strlen(ch)); while(1); return 0;}