随笔 - 30  文章 - 67  trackbacks - 0
<2020年9月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用链接

留言簿(8)

随笔分类

随笔档案

文章档案

收藏夹

Oops

搜索

  •  

积分与排名

  • 积分 - 77274
  • 排名 - 267

最新评论

阅读排行榜

评论排行榜

        今天看见大家在讨论atoi这个函数,我也凑个热闹,学习下atoi函数的用法,记得当时学C语言,以为就只能将全是数字的字符串转化成整数,现在明白了远不至如此。

1、能够将从当前开始的字符(数字或+、-)到第一个不是数字的字符结束的数字字符串,转化成整数;
      这个也就是有人在blog中谈论的前缀匹配。
2、需要注意的指针在这个过程中的指向发生了改变

下面给出我的atoi实现代码
int aatoii(const char * str)
{
    
if(str == NULL) return 0;

    
int result = 0;
    
int sign = 1;
    
if( ('0'<= str[0&& str[0<= '9'||(str[0]=='-'|| str[0]=='+')
    {
        
if(str[0== '+' || str[0== '-')
        {
            
if(str[0]=='-')
            {
                sign 
= -1;
            }
            str
++;
        }
    }
    
else
    {
        
return 0;
    }

    
while('0'<= *str && *str <= '9')
    {
        result 
= result*10 + (*str++ - '0');
    }

    
return result;
}



修改版:
int aatoii(const char * str)
{
    
if(str == NULL) return 0;

    
int result = 0;
    
int sign = 1;
    
if( ('0'<= str[0&& str[0<= '9'||(str[0]=='-'|| str[0]=='+')
    {
        
if(str[0== '+' || str[0== '-')
        {
            
if(str[0]=='-')
            {
                sign 
= -1;
            }
            str
++;
        }
    }
    
    
    
while('0'<= *str && *str <= '9' )
    {
        result 
= result*10 + (*str++ - '0');
    }

    
return result * sign;
}

后面说我没溢出判断:
我仔细想了想:我认为没必有,由于我保证了传进来的str是有意义的:
无外乎这几种情况: {'\0'}, {'+', '\0'}, {'1', '2', '\0'} , {'a', 'b', '1', '2', '\0'},这些都应该没有问题
,由于while('0' <= *str && *str <= '9'),等于间接就判断了。

修改版二:
现在发现我对溢出的理解是错误,下面给出代码
ps:发现linux的颜色真好看,




 
3、今天我才明白const char* str; 是修饰字符串不能改变的,而不是指针, 修饰常量指针的是char* const str;

    那我就说说吧:
    const int * const pint;  //一个const指针,指向一个const成员
    const int * pint;   //一个非const指针, 指向一个const成员
    int *pint;  //一个非const指针,指向一个非const成员
    int * const pint;  //一个const指针,指向一个非const成员
    int const * pint; //和第二个一样, 一个非const指针, 指向一个const成员, 这个不常用




posted on 2011-03-13 13:08 Cunch 阅读(16978) 评论(10)  编辑 收藏 引用 所属分类: C++

FeedBack:
# re: atoi函数实现 2011-03-13 18:24 hook
1. sign没有用到。估计是您疏漏了吧。
2. 既然到第一个非数字为止,那么一开始判断[0]非数字就return0的代码是多余的,后面循环自然会结束返回0;完全可以去掉最外层的那个if/else,只需要判断[0]是否正负号即可
3. 溢出没有判断。这才是atoi的考察点和陷阱。

坦白说atoi是最常见的面试/笔试题了,您这个程序要是拿去应试估计是不及格的。  回复  更多评论
  
# re: atoi函数实现 2011-03-13 18:59 陈梓瀚(vczh)
TM他当时就应该把const T的语法设计成const(T),然后就可以有const(int) *和const(int *)了。  回复  更多评论
  
# re: atoi函数实现 2011-03-13 19:58 Cunch
@hook
谢谢你的回答,让我明白我的差距,我平时就不注意这个溢出问题。  回复  更多评论
  
# re: atoi函数实现 2011-03-13 19:59 Cunch
@陈梓瀚(vczh)
我也是很疑惑这个问题。你的编译器做的真不错。  回复  更多评论
  
# re: atoi函数实现 2011-03-13 20:55 月下圆舞曲
@Cunch
话说还是得判断溢出的吧。。直接来个大点的数字,要是这么写,return就乱了
@陈梓瀚(vczh)
恩,这个const位置一变性质就变的设计的确挺恶心,而且没必要,要是按你写的弄看着清楚多了

  回复  更多评论
  
# re: atoi函数实现 2011-03-14 21:13 千暮(zblc)
发下我的:
1、无数字返回0
2、溢出返回上下界


int aatoi(const char * str)
{
if(!str)return 0;
__int64 test=+0;
char sign=0 ;

if( ( str[0]=='-' ?--sign:( str[0]=='+'?++sign:sign++ ) ) )
str++;
while('0'<= *str && *str <= '9')
{
test = test*10 + (*str++ - '0');
if(test*sign> 2147483646) return 2147483647;
else if(test*sign< -2147483647) return -2147483648;
}
return int(test)*sign;
}  回复  更多评论
  
# re: atoi函数实现 2011-03-15 09:05 Cunch
@千暮(zblc)
你的溢出判断有问题阿, 你看看我新添加的代码  回复  更多评论
  
# re: atoi函数实现 2011-03-15 15:22 千暮(zblc)
@Cunch
那是编译器警告误报,因为恰好达到那个边界 实际上是不会有问题。

你的溢出通过/10检测来返回的话,就比默认atoi的转化力低了。  回复  更多评论
  
# re: atoi函数实现 2011-05-07 20:46 hust_ruan
贴一下我写的,求测试!!!!!

int my_atoi(const char* str)
{
assert(str != 0);
const unsigned int maxTest = INT_MAX / 10;
const unsigned int maxDigit = INT_MAX % 10;

int sign = 1;
unsigned int value = 0;

while( *str == ' ' || *str == '\t')
str++;

if( *str == '+' || *str == '-')
{
if(*str == '-')
sign = -1;
str++;
}

while( *str >= '0' && *str <= '9' )
{
unsigned int digit = *str - '0';

if( (value > maxTest) ||
(value == maxTest) && (digit > maxDigit ) )
{
return sign > 0 ? INT_MAX : INT_MIN;
}

value = value * 10 + digit;
str++;

}
return value * sign;

}  回复  更多评论
  
# re: atoi函数实现 2015-05-09 11:16 latte
请问博主,*str++ - '0',这个地方为什么要减'0'?  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理