c - 使用 unsigned int 而不是 unsigned short 改变行为

标签 c unsigned short integer-promotion

我正在尝试使用 K&R 编写的 The C Programming Language 中的 htoi(char*) 函数(练习 2-3,第 43 页)。

该函数用于将十六进制字符串转换为以 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 时,我得到一个无限循环。

所以当我在 htoi(char* s) 中从 s 的后面开始时,i >= firstIndex 永远不会计算为 false .

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

最佳答案

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

您可以更改:

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

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

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

关于c - 使用 unsigned int 而不是 unsigned short 改变行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28931626/

相关文章:

在 C 中将有符号值转换为无符号值

c# - 将 Int 转换为两个 Shorts 返回填充数据/负值

c++ - OpenCV 子矩阵问题(短类型)

c - 在 C 代码中使用 ReadFile

c - 当我做这个作业时到底发生了什么

c++ - 在 C++ 中将文件读入二进制数组

java - 将 java.net.InetAddress 转换为长

c - 在 C 中查找 short int 变量的最大值

c - 在 Windows C 中获取与真实硬件以太网 Controller 关联的 IP 地址

algorithm - 间接寻址在此代码中如何工作?