2015-03-08 52 views
3

我试图从C编程语言K & R(Excercise 2-3,第43页)的htoi(char*)函数。使用unsigned int而不是无符号的短更改行为

功能旨在为十六进制字符串转换为基座10

我相信我有它的工作。这是我的代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 

enum {hexbase = 16}; 
typedef enum{false, true} bool; 

unsigned int htoi(char* s); 
bool hasHexPrefix(char* s); 

int main(int argc, char** argv) { 

    if(argc <= 1) { 
     printf("Error: Not enough arguments.\n"); 
     return EXIT_FAILURE; 
    }else { 
     for(int i = 1; i < argc; i++) { 
      unsigned int numericVal = htoi(argv[i]); 
      printf("%s => %u\n",argv[i],numericVal); 
     } 
    } 
} 

unsigned int htoi(char* s) { 
    unsigned int output = 0; 
    unsigned int len = (unsigned int)(strlen(s)); 

    unsigned short int firstIndex = hasHexPrefix(s) ? 2 : 0; 

    /* start from the end of the str (least significant digit) and move to front */ 
    for(int i = len-1; i >= firstIndex; i--) { 
     int currentChar = s[i]; 
     unsigned int correspondingNumericVal = 0; 
     if(currentChar >= '0' && currentChar <= '9') { 
      correspondingNumericVal = currentChar - '0'; 
     }else if(currentChar >= 'a' && currentChar <= 'f') { 
      correspondingNumericVal = (currentChar - 'a') + 10; 
     }else if(currentChar >= 'A' && currentChar <= 'F') { 
      correspondingNumericVal = (currentChar - 'A') + 10; 
     }else { 
      printf("Error. Invalid hex digit: %c.\n",currentChar); 
     } 
     /* 16^(digitNumber) */ 
     correspondingNumericVal *= pow(hexbase,(len-1)-i); 
     output += correspondingNumericVal; 
    } 

    return output; 
} 

bool hasHexPrefix(char* s) { 
    if(s[0] == '0') 
     if(s[1] == 'x' || s[1] == 'X') 
      return true; 

    return false; 
} 

我的问题是从htoi(char*)功能下面一行:

unsigned short int firstIndex = hasHexPrefix(s) ? 2 : 0; 

当我删除short使firstIndexunsigned int而非unsigned short int,我得到无限循环。

所以当我从s后面htoi(char* s)开始,i >= firstIndex从来没有评估为假。

为什么会发生这种情况?我是否错过了一些微不足道的东西,或者我是否做了非常错误的事情导致这种未定义的行为?

+0

哪个版本的K&R?第一次? – user3528438 2015-03-08 20:56:36

+0

这是第二版。 – 2015-03-08 21:23:09

+0

即使程序调用未定义的行为,问题的标题也会很糟糕。 “未定义的行为”在C语言中具有特定的含义,因为程序没有做到你想要的东西,所以不适用。 – 2015-03-08 21:48:27

回答

4

firstIndexunsigned int,在i >= firstIndex然后i被转换为unsigned int因为通常的算术转换的。所以如果i是负数,它会在比较表达式中变成一个大整数。当firstIndexunsigned short int,i >= firstIndex,firstIndex被提升为int并且比较两个有符号整数。

您可以更改:

for(int i = len-1; i >= firstIndex; i--) 

for(int i = len-1; i >= (int) firstIndex; i--) 

有在两种情况下相同的行为。

+0

我宁愿为(无符号i = len-1; i> = firstIndex; i--) – 2015-03-08 21:27:27

+3

@GRC做什么,因为你会在同一个问题OP下跌。以'firstIndex'值为'0'为例,那么'i> = firstIndex'将始终为真。 – ouah 2015-03-08 21:38:17

+0

另一种可能的结构是'for(unsigned i = len; i--;)' – 2015-03-08 21:46:40

相关问题