代码:
1 long __cdecl atol( 2 const char *nptr 3 ) 4 { 5 int c; /* current char */ 6 long total; /* current total */ 7 int sign; /* if '-', then negative, otherwise positive */ 8 9 /* skip whitespace */10 while ( isspace((int)(unsigned char)*nptr) )11 ++nptr;12 13 c = (int)(unsigned char)*nptr++; sign = c; /* save sign indication */14 if (c == '-' || c == '+')15 c = (int)(unsigned char)*nptr++; /* skip sign */16 17 total = 0;18 19 while (isdigit(c)) {20 total = 10 * total + (c - '0'); /* accumulate digit */21 c = (int)(unsigned char)*nptr++; /* get next char */22 }23 24 if (sign == '-')25 return -total;26 else27 return total; /* return result, negated if necessary */28 }
为什么要用 (int)(unsigned char)?
因为在char 类型强制转换成int类型时,若char类型数是负数(最高位为1)有些编译器会将最高字节填充0xFF
1 for(int i = 128; i < 131; i++) 2 { 3 int c = (char)i; 4 int d = (unsigned char)i; 5 printf("%d %d\n", c, d); 6 } 7 8 输出: 9 -128 12810 -127 12911 -126 13012 请按任意键继续. . .
因为isspace(),isdigit()这类函数接受一个int 参数,参数的值必须是一个可以用unsigned char 表示的值或者是EOF,以下是 man 手册的原文:
int isspace(int c);int isdigit(int c);...These functions check whether c, which must have the value of anunsigned char or EOF,falls into a cetern charcter class according to the current locale.所以需要用c = (int)(unsigned char)*nptr++,来确保从 *nptr++ 到 c 是进行零扩展而不是符号扩展,保证 c 中存放的是一个unsigned char 所能表示的值。