這是兩道經常考到的筆試題,看似簡單的實現,其實專注到細節,還是有很多需要注意扣分的地方。
atoi實現:
1 #include <iostream> 2 #include<ctype.h> 3 using namespace std; 4 5 typedef enum status{ 6 OK,ERROR 7 }Status; 8 9 Status myErrno = ERROR; 10 int my_atoi(const char *p); 11 int main() 12 { 13 char *mystr = "45678910"; 14 int ret = my_atoi(mystr); 15 cout << ret << endl; 16 return 0; 17 } 18 19 //實現atoi函式,將字串轉換為數字 20 int my_atoi(const char *p){ 21 myErrno = ERROR; 22 if(NULL == p) 23 return 0; 24 25 int ret = 0; 26 27 const char *temp = p; 28 29 //判斷如果是前幾位為空格,則向前移動字串位置 30 while(isspace(*temp)) 31 temp++; 32 33 //判斷符號位,是否為負數 34 bool minus = *temp=='-' ? true : false; 35 36 //有符號位 37 if('+' == *temp || '-' == *temp) 38 ++temp; 39 40 while(*temp != '\0'){ 41 if(isdigit(*temp)){ //是數字情況下 42 if((!minus && ret > 0x7FFFFFFF) || (minus && -minus < 0x80000000)){ 43 //若當前數值範圍超出int所能表達的範圍 44 myErrno = ERROR; 45 return 0; 46 } 47 48 ret = ret*10 + (*temp++ - '0'); 49 }else{ 50 //某位不是數字 51 myErrno = ERROR; 52 return 0; 53 } 54 55 } 56 57 if(*temp == '\0'){ 58 myErrno = OK; 59 } 60 61 return minus ? -ret : ret; 62 }
strcpy的實現:
1 //實現trcpy函式 2 char *my_strcpy(char *dest,const char *src){ 3 assert(dest != NULL && src != NULL); 4 5 char *ret = dest; 6 while((*dest++ = *src++) != '\0'); 7 8 return ret; 9 }
對於strcpy的實現,還是會有問題的,需要考慮到記憶體重疊的情況,比如:
char *str = 'abcde';
strcpy(str,str+1); //結果為bcde
strcpy(str+1,str); //期望結果:aabcde,但執行會報錯,因為str記憶體有重疊,會把'\0'覆蓋掉
但是如果呼叫系統中的strcpy是不會有這個問題,其實要解決這個問題需要配合memcpy來使用
1 char *my_strcpy(char *dest,const char *src){ 2 assert(dest != NULL && src != NULL); 3 4 char *ret = dest; 5 memcpy(dst,src,strlen(src)+1); 6 7 return ret; 8 }
至於memcpy的實現,建議參考 http://blog.csdn.net/gpengtao 這為大牛的實現:
1 void * my_memcpy(void *dst,const void *src,unsigned int count) 2 { 3 assert(dst); 4 assert(src); 5 void * ret = dst; 6 if (dst <= src || (char *)dst >= ((char *)src + count))//源地址和目的地址不重疊,低位元組向高位元組拷貝 7 { 8 while(count--) 9 { 10 *(char *)dst = *(char *)src; 11 dst = (char *)dst + 1; 12 src = (char *)src + 1; 13 } 14 } 15 else //源地址和目的地址重疊,高位元組向低位元組拷貝 16 { 17 dst = (char *)dst + count - 1; 18 src = (char *)src + count - 1; 19 while(count--) 20 { 21 *(char *)dst = *(char *)src; 22 dst = (char *)dst - 1; 23 src = (char *)src - 1; 24 } 25 } 26 return ret; 27 }