一、atoi 函数的功能
cplusplus网站
(这个网站可以查询C语言中的函数感兴趣的可以看看)
我们从这个里面可以知道,函数要包含的头文件是 <stdlib.h> 。
int atoi(const char* str)
int atoi (const char* str)
返回类型 函数名 输入值
由此我们可以知道,这个函数的功能是,我们输入一个字符串,函数给我们返回,一个 int 类型的整数。
二、功能介绍
那是什么字符都可以吗?我们来看下面的介绍。
接下来,我们探究一下这些功能。
功能一 : 如果开始遇到空格,将会一直过滤
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
num = atoi("123");
printf("%d\n", num);
num = atoi(" 123");
printf("%d\n", num);
return 0;
}
运行结果:
我们发现空格被过滤掉了,那如果空格在中间呢?
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
num = atoi(" 12 3");
printf("%d\n", num);
return 0;
}
运行结果:
我们发现在第二次遇见空格时,后面的数字没有被显示出来。
那我们得出结论
atoi 函数在一开始遇见空格时会过滤掉
第二次遇见空格就会结束运行
功能二、“+” “-”号会影响数字的正负
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
num = atoi("+123");
printf("%d\n", num);
num = atoi("-123");
printf("%d\n", num);
return 0;
}
运行结果:
我们发现,正负号会影响到数字,若为 “+” 则不显示,若为 “ - ” 则在数字前加上负号。
那么同样,如果正负号被加在中间会不会输出呢?
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
num = atoi("+12+3");
printf("%d\n", num);
num = atoi("-12-3");
printf("%d\n", num);
return 0;
}
运行结果:
我们同样发现第二次遇见正负号,后面的数字没有显示出来。
我们得出结论
函数在数字前遇见 “+” 时会忽略 “+”
函数在数字前遇见“ - ” 时会忽略“ - ”
在第二次遇见“ + ”或者“ - ”时会忽略,并且不显示后面的数字
功能三:遇见非数字字符时,就会停止
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
num = atoi(" 11111a23");
printf("%d\n", num);
num = atoi(" a1111123");
printf("%d\n", num);
return 0;
}
运行结果:
我们发现当遇见非数字字符时,函数就会结束运行,并且打印的是数字0,这个0可能是函数返回的,也有可能是我们对num初始化时给的。
我们来看接下来的程序:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 1;
num = atoi(" a11111a23");
printf("%d\n", num);
return 0;
}
运行结果:
当我们将 num 初始化成 1 时,我们发现打印的值还是 0 ,那就说明,当函数在一开始就结束运行时,会返回值,这个值是 0 。
我们得出结论
函数在遇见非数字字符时就会结束运行
函数在没有识别到数字字符时会返回,并且返回值是0
功能四:当数字超出int最大存储,会返回最大值
我们知道函数返回值是 int 类型的,int 类型有四个字节,那当数字超出了,就可能有两种结果
第一种,将超出部分截取掉
第二种,输出 int 最大值,也就是 INT_MAX
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
num = atoi("1111111111111111");
printf("INT_MAX=%d\n", INT_MAX);
printf("num =%d\n", num);
return 0;
}
运行结果:
我们发现,当输入了一堆 1 ,明显超出 int 的最大储存时,输出的是 int 类型的最大数,也就是 INT_MAX
我们得出结论
当数字字符串,超出 int 类型的最大储存时,会输出 INT_MAX
总结
<1>
函数在一开始遇见空格时会过滤掉
第二次遇见空格就会结束运行
<2>
函数在数字前遇见 “+” 时会忽略 “+”
函数在数字前遇见“ - ” 时会忽略“ - ”
在第二次遇见“ + ”或者“ - ”时会忽略,并且不显示后面的数字
<3>
函数在遇见非数字字符时就会结束运行
函数在没有识别到数字字符时会返回,并且返回值是0
<4>
当数字字符串,超出 int 类型的最大储存时,会输出 INT_MAX
当然了这么多符号排列组合,还有一些情况我可能没有考虑到,但是对这个函数的正常使用情况也差不多了,比如连续两个” + “这种阴间情况,这个我们就不考虑了。下面还要复现函数,咱就别太钻牛角尖了。
我是懒狗
三、函数实现
功能一
<1>
函数在一开始遇见空格时会过滤掉
第二次遇见空格就会结束运行
我们若想实现这个功能,需要了解一个函数 “isspace”
头文件:<ctype.h>
功能,输入字符,返回一个 int 类型的整数
由此可知,如果进入函数的是空格就会返回一个不为 0 的数,如果不是空格就会返回 0 。
今天的主角不是它,就粗略介绍一下,感兴趣的可以根据我上面给出的网站自己查一下研究研究。
所以,为了完成功能一,就有了下面的代码:
//isspace判断是否为空格,并跳过空格。
while (isspace(*str))
{
str++;
}
//后面的*str,不会再有空格了
代码走完之后后面的就一定不是空格了。
功能二
<2>
函数在数字前遇见 “+” 时会忽略 “+”
函数在数字前遇见“ - ” 时会忽略“ - ”
在第二次遇见“ + ”或者“ - “时会忽略,并且不显示后面的数字
若想完成功能二,会有下面的代码:
//判断正负号
int flg = 1;
// flg 将正负号判断并保存下来
if (*str == '+')
{
flg = 1;
str++;
}
else if (*str == '-')
{
flg = -1;
str++;
}
建立 flg 是为了保存正负号
如果为‘ + ’那么 flg 为 1
如果为” - “那么 flg 为 -1
那么到时我们要返回 int 类型的数时我们将 flg 与之相乘,就把正负号加了上去。
功能三
<3>
函数在遇见非数字字符时就会结束运行
函数在没有识别到数字字符时会返回,并且返回值是0
若要完成功能三,有下面的代码:
//判断是否为数字字符
long long ret = 0;
while (*str!='\0')
{
if ((*str) >= '0' && (*str) <= '9')
{
ret = ret * 10 + (*str - '0') * flg;
}
else
{
return (int)ret;
}
str++;
}
这个代码我为大家解读一下
第一个 ret 是为了保存被转换的数字,为什么时long long 的数据类型,下面会为大家解释。
while 循环中是” *str!=‘\0’ “意思就是,如果一直都没有意外直到字符串结束,那么就是到了字符串末尾 ‘ \0 ’ 处,结束循环。
接下来是 if 判断语句((*str) >= ‘0’ && (*str) <= ‘9’),就是根据Ascll码值对(*str)进行判断,判断是否为数字字符。
如果是,ret = ret * 10 + (*str - ‘0’) * flg
因为最开始被识别的数字,于数字整体是在高位所以需要对ret 乘十
后面的 (str - ‘0’) * flg,因为str 是数字字符,减去 ‘ 0 ’ 则变成数字大小
如果不是,return ret
直接返回,所以遇见非数字字符时,会直接返回。
功能四
<4>
当数字字符串,超出 int 类型的最大储存时,会输出 INT_MAX
到了功能四,上面功能三中为什么 ret 用 long long 的数据类型就有解释了。
因为当 ret 中存储了超出 int 数据类型的数字时,多出的部分会被截断,所以我们要用long long 存储,然后再判断,如果超出了就返回INT_MAX这个值。
My_atoi
最后的函数就是这样的,大家可以写出来试试,看看与atoi是否功能一样。
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<assert.h>
int My_atoi(const char* str)
{
//判断str是否为空,并且判断str中是否有值
// 为空则报错,没有值则返回0
assert(str);
if (*str == '\0')
{
return 0;
}
//isspace判断是否为空格,并跳过空格。
while (isspace(*str))
{
str++;
}
//后面的*str,不会再有空格了
//判断正负号
int flg = 1;
// flg 将正负号判断并保存下来
if (*str == '+')
{
flg = 1;
str++;
}
else if (*str == '-')
{
flg = -1;
str++;
}
//判断是否为数字字符
long long ret = 0;
while (*str!='\0')
{
if ((*str) >= '0' && (*str) <= '9')
{
ret = ret * 10 + (*str - '0') * flg;
if (ret >= INT_MAX)
{
ret = INT_MAX;
}
if (ret <= INT_MIN)
{
ret = INT_MIN;
}
}
else
{
if (ret >= INT_MAX)
{
ret = INT_MAX;
}
return (int)ret;
}
str++;
}
//返回数据
return (int)ret;
}
int main()
{
int num;
num = My_atoi("");
printf("%d", num);
return 0;
}