C中atoi和strcpy的自定義實現

範長法@三月軟體發表於2014-10-17

  這是兩道經常考到的筆試題,看似簡單的實現,其實專注到細節,還是有很多需要注意扣分的地方。

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 }

 

相關文章