atoi-字符串转Int的实现

来源:互联网 发布:mysql 架构 编辑:程序博客网 时间:2024/06/09 21:17

要考虑的问题

  1. 前导空白(空格和Tab)
  2. 溢出
  3. 异常字符

处理方法

  1. 首先过滤前导空白,直到遇到非空白符
  2. 若接下来的字符是正负号或者数字,继续执行下一步;否则,返回0,结束
  3. 一直读取,直至遇到非数字字符(包括’\0’)
  4. 若这段数字溢出,则相应的返回 INT_MAX 或者 INT_MIN ;否则,返回转换后的结果,结束

代码如下

#include "stdio.h"#define INT_MAX 2147483647#define INT_MIN (-2147483647-1)#define MAX_DIGITS 10 // int类型的最大位数const char* INT_MAX_STR = "2147483647";const char* INT_MIN_STR = "2147483648";bool overflow(char* num, int flag){    char* INT_BOUND = (flag == 1) ? INT_MAX_STR : INT_MIN_STR;    for(int i = 0; i < MAX_DIGITS; i++)    {        if(num[i] > INT_BOUND [i])            return true;        else if(num[i] < INT_BOUND [i])            return false;    }    return false;}bool isDigit(char ch){    return (ch >= '0' && ch <= '9');}int atoi(char * str){    int value = 0;     while(*str == ' ' || *str == '\t')        *str++;    if(*str == '\0')        return 0;    int flag = 1;    if(*str == '+' || *str == '-')    {        if(*str == '-')            flag = -1;        *str++;    }    char num[MAX_DIGITS];    int index = 0;    while(isDigit(*str))    {        if(index >= MAX_DIGITS) // overflow            return (flag == 1) ? INT_MAX : INT_MIN;        num[index++] = *str;        *str++;    }    if(index == MAX_DIGITS && overflow(num, flag)) // overflow        return (flag == 1) ? INT_MAX : INT_MIN;    for(int i = 0; i < index; i++)        value = value * 10 + num[i] - '0';    return value * flag;}

相关问题

关于INT_MIN的定义,若写成-2147483648,则当在程序中使用INT_MIN时,编译器会出现警告信息:

warning C4146:一元负运算符应用于无符号类型,结果仍为无符号类型;

编译器把-2147483648看做了对2147483648取负,而2147483648超出了有符号整数的范围,编译器就把他当做了无符号数0x80000000=2147483648。

在C语言中,若有符号数与无符号数进行运算,C语言就隐式的将有符号参数强制转换为无符号数,并假设两个数都是非负的。(深入理解计算机系统 P48)

在有些情况下这会导致一些错误,比如下面的表达式:

(0>INT_MIN) ? 1 : -1;

表达式的结果是 -1 就不难理解了。

0 0
原创粉丝点击