atoi-字符串轉Int的實現

要考慮的問題

  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 就不難理解了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章