1、分析
和真正的C++中atoi函数还是有区别的哦~~~
情况 | Input | Output |
---|---|---|
空 | “” | 0 |
空格 | ” “ | 0 |
空格系列 | ” abc” | 0 |
空格系列2 | ” 123” | 123 |
符号 | “++1” | 0 |
符号2 | “+1 | 1 |
符号3 | “+” | 0 |
符号4 | “56+” | 56 |
小数 | 3.9999 | 3 |
0 | 000001 | 1 |
字母 | 345a2b | 345 |
字母2 | a23 | 0 |
综合 | ” -0024.34b” | -24 |
综合 | “2 -678” | 2 |
可以看出:
1、如果第一位是空格,扫描看后面连续几个空格,直到不是空格,常规判断后面的;
2、如果第一位是符号,判断它不同时是最后一位,后面是否紧跟数字;
3、如果第一位是0,应使数位左移,直到第一位不是0;
4、如果第一位是数字,判断后面是否紧跟数字,直到不是数字,输出数字部分;
5、如果第一位是其他,不是数字,输出0;
所以判断第一位很重要!
2、第一位的预判:
while (str[0] == ' ')//如果第一位是空格,数位左移
{
for (j = 0; j < len; j++)
str[j] = str[j + 1];
len--;
}
if (str[0] == '+' || str[0] == '-')//如果第一位是符号
{
if (len>1)//符号后面还有
{
sym = str[0];//储存符号
for (j = 0; j < len; j++)//数位左移
str[j] = str[j + 1];
len--;
}
else isnum = 0;//单独一个符号 不是数字
}
while (str[0]=='0')//排除掉前面都是0的情况
{
for (j = 0; j < len; j++)//数位左移
str[j] = str[j + 1];
len--;
}
经过以上判断+不断数位左移,现在应为正式的数字部分
i = 0;
while (str[i]>='0'&&str[i]<='9')
{
isnum = 1;
i++;
}
len = i;//记录这个int型数字有多长
如果不是数字,bool类型的isnum值默认为0
3、溢出计算:
如果是数字,按位数相加,注意,要检验是否溢出。
int型最大值为2147483647,而最小值为-2147483648
最小值去掉符号后,比最大值还大,所以如果是负数,作为无符号数判断时有可能溢出。
if (isnum)//如果是一个int型数字
{
for (i = 0; i < len; i++)
{
int temp = (str[i] - '0') * pow(10, len - 1 - i);
if (sum <= MAX - temp )//不断检验是否溢出 MAX=2147483647
sum += temp;
else//如果溢出,注意因为之前去掉了符号,检验原数是否为负数
{
if (sym == '-')//之前存储的符号
{
if (0 - sum >= MIN + temp)//负数最小 MIN=-2147483648
{
sum = 0 - sum - temp;
return sum;
}
else return MIN;//负数溢出输出MIN值
}
else return MAX;//正数溢出输出MAX值
}
}
if (sym == '-')//负数无溢出时
sum = 0 - sum;
}