atol 函数
代码:
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 else 27 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 128 10 -127 129 11 -126 130 12 请按任意键继续. . .
因为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 所能表示的值。