atoi implementation in C

前端 未结 6 1412
伪装坚强ぢ
伪装坚强ぢ 2020-12-23 18:34

I can\'t understand the following atoi implementation code, specifically this line:

k = (k << 3) + (k << 1) + (*p) - \'0\';
<         


        
6条回答
  •  一生所求
    2020-12-23 18:59

    Interestingly, the man page for atoi doesn't indicate setting of errno so if you're talking any number > (2^31)-1, you're out of luck and similarly for numbers less than -2^31 (assuming 32-bit int). You'll get back an answer but it won't be what you want. Here's one that could take a range of -((2^31)-1) to (2^31)-1, and return INT_MIN (-(2^31)) if in error. errno could then be checked to see if it overflowed.

    #include 
    #include   /* for errno */
    #include  /* for INT_MIN */
    #include  /* for strerror */
    
    extern int errno;
    
    int debug=0;
    int atoi(const char *c)
    {
        int previous_result=0, result=0;
        int multiplier=1;
    
        if (debug) printf("converting %s to integer\n",c?c:"");
        if (c && *c == '-')
        {
            multiplier = -1;
            c++;
        }
        else
        {
            multiplier = 1;
        }
        if (debug) printf("multiplier = %d\n",multiplier);
        while (*c)
        {
            if (*c < '0' || *c > '9')
            {
                return result * multiplier;
            }
            result *= 10;
            if (result < previous_result)
            {
                if (debug) printf("number overflowed - return INT_MIN, errno=%d\n",errno);
                errno = EOVERFLOW;
                return(INT_MIN);
            }
            else
            {
                previous_result *= 10;
            }
            if (debug) printf("%c\n",*c);
            result += *c - '0';
    
            if (result < previous_result)
            {
                if (debug) printf("number overflowed - return MIN_INT\n");
                errno = EOVERFLOW;
                return(INT_MIN);
            }
            else
            {
                previous_result += *c - '0';
            }
            c++;
        }
        return(result * multiplier);
    }
    
    int main(int argc,char **argv)
    {
        int result;
        printf("INT_MIN=%d will be output when number too high or too low, and errno set\n",INT_MIN);
        printf("string=%s, int=%d\n","563",atoi("563"));
        printf("string=%s, int=%d\n","-563",atoi("-563"));
        printf("string=%s, int=%d\n","-5a3",atoi("-5a3"));
        if (argc > 1)
        {
            result=atoi(argv[1]);
            printf("atoi(%s)=%d %s",argv[1],result,(result==INT_MIN)?", errno=":"",errno,strerror(errno));
            if (errno) printf("%d - %s\n",errno,strerror(errno));
            else printf("\n");
        }
        return(errno);
    }
    

提交回复
热议问题