一、字符串的strcpy與strncpy函數
1、編程實現strcpy函數(筆試很容易考到)
要求:
原型:char *stpcpy(char *strDest,char *strSrc);
頭文件:#include <string.h>
功能:把src所指由NULL結束的字符串復制到dest所指的數組中。
說明:src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。
返回指向dest結尾處字符(NULL)的指針。
strcpy的代碼實現:
char * strCpy(char * strDest,const char * strSrc) //[1] {
//函數assert的頭文件為#include<assert.h> assert((strDest != NULL)&&(strSrc != NULL)); //[2] char * strDestCopy=strDest; //[3] while ((*strDest++ = *strSrc++) != '\0'); //[4] return strDestCopy; //[5] }
代碼的分析:
代碼[1]:可能會忘記代碼中的參數列表以及返回值
代碼[2]:很多人會忘記對字符串指針的檢查,這一部分能體現程序員的嚴謹性,主要體現在一下三點,
a、不檢查指針的有效性,說明答題者不注重代碼的健壯性
b、檢查指針的有效性時使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),說明答題者對C語言中類型的隱式轉換沒有深刻認識
c、檢查指針的有效性時使用((strDest==0)||(strSrc==0)),說明答題者不知道使用常量的好處
代碼2也可以寫: if ((strDest == NULL)||(strSrc == NULL))
throw "Invalid argument(s)"; //throw為拋出異常
代碼[3]: 忘記保存原始的strDest值,說明答題者邏輯思維不嚴密。
代碼[4]:沒有什么硬性的要求,這部分功能比較容易實現,考慮到邊界問題就可以了
代碼[5]:返回值是為了鏈式調用(一般情況下放回值是字符串類型的指針都是為了鏈式調用)
2、編程實現strncpy函數
要求:
原型: char *strncpy(char *strDest, char *strSrc, int n);
頭文件:#include <string.h>
功能:把src所指由NULL結束的字符串的前n個字節復制到dest所指的數組中。
說明:
1、如果src的前n個字節不含NULL字符,則結果不會以NULL字符結束。
2、如果src的長度小於n個字節,則以NULL填充dest直到復制完n個字節。
3、src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。
返回值:指向dest的指針。
strncpy代碼實現:
char * my_strncpy(char *strDest, const char *strSrc, int num) { assert((strDest != NULL) && (strSrc != NULL)); //if (strDest == NULL || strSrc == NULL) return NULL; //保存目標字符串的首地址 char *strDestcopy = strDest; while ((num--)&&(*strDest++ = *strSrc++) != '\0'); //如果num大於strSrc的字符個數,將自動補'\0' if (num > 0) { while(--num) { *strDest++ = '\0'; } } return strDestcopy;
}
代碼分析:
1、代碼strncpy與代碼strcpy其實相差不大,
2、需要考慮到,如果src的長度小於n個字節,則以NULL填充dest直到復制完n個字節。