atoi函数源代码
isspace(int x) { if(x==' '||x=='\t'||x=='\n'||x=='\f'||x=='\b'||x=='\r') return 1; else return 0; } isdigit(int x) { if(x<='9'&&x>='0') return 1; else return 0; } int atoi(const char *nptr) { int c; /* current char */ int total; /* current total */ int sign; /* if '-', then negative, otherwise positive */ /* skip whitespace */ while ( isspace((int)(unsigned char)*nptr) ) ++nptr; c = (int)(unsigned char)*nptr++; sign = c; /* save sign indication */ if (c == '-' || c == '+') c = (int)(unsigned char)*nptr++; /* skip sign */ total = 0; while (isdigit(c)) { total = 10 * total + (c - '0'); /* accumulate digit */ c = (int)(unsigned char)*nptr++; /* get next char */ } if (sign == '-') return -total; else return total; /* return result, negated if necessary */ }
看了atol的实现,发现char到int的转换比较奇怪:c = (int)(unsigned char)*nptr++; 先将char转为unsigned再转为int,于是测试了下,发现有如下结果:
#include<stdio.h> void main() { char c = 0x80; unsigned char uc = 0x80; printf("c2i=%x,c2ui=%x,uc2i=%x,uc2ui=%x\n", (int)c,(unsigned int)c,(int)uc,(unsigned int)uc ); }
结果:
c2i=ffffff80,c2ui=ffffff80,uc2i=80,uc2ui=80
可以发现,如果char默认为signed(可能是平台相关的),则将char转为int或uint时,会有符号位扩展,而unsigned char则不会。atol/atoi函数应该希望避免符号位扩展而带来问题。不过,好在数字0到9的ACSII码并没有超过0x7F,因此是否事先转成unsigned char应该不会对结果有影响。
itoa()函数有3个参数:第一个参数是要转换的数字,第二个参数是目标字符串,第三个参数是转移数字时所用 的基数。
时间: 2024-10-03 14:56:33