2015-03-08 4 views
3

Я пытаюсь использовать функцию htoi(char*) с языка программирования C на K & R (Упражнение 2-3, стр. 43).Использование 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 сделать firstIndex в unsigned int, а не как unsigned short int, я получаю бесконечное петля.

Так что, когда я начинаю со спины s в htoi(char* s), i >= firstIndex никогда не будет ошибочным.

Почему это происходит? Я пропустил что-то тривиальное или сделал что-то ужасно неправильно, чтобы вызвать это неопределенное поведение?

+0

Какое издание K & R? Первый? – user3528438

+0

Это второе издание. –

+0

Название вопроса было бы ужасным, даже если программа вызывала неопределенное поведение. «Неопределенное поведение» имеет определенное значение в C, использовать его не так просто, потому что программа не делает то, что вы хотите. –

ответ

4

Когда firstIndex является unsigned int, в i >= firstIndex затем i преобразуются в unsigned int из-за обычные арифметические преобразования. Поэтому, если i отрицательный, он становится большим целым числом в выражении сравнения. Когда firstIndex - unsigned short int в i >= firstIndex, firstIndex - int и сравниваются два значащих целых числа.

Вы можете изменить:

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

в

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

иметь такое же поведение в обоих случаях.

+0

Я предпочел бы сделать для (unsigned i = len-1; i> = firstIndex; i--) –

+3

@GRC, который не будет работать, поскольку вы будете падать в той же проблеме, что и в OP. Возьмем, например, значение 'firstIndex'' 0', тогда 'i> = firstIndex' всегда будет true. – ouah

+0

Другая возможная структура: 'for (unsigned i = len; i--;)' –

 Смежные вопросы

  • Нет связанных вопросов^_^