![](/img/trans.png)
[英]Printf in unsigned short int and unsigned int using %d
[英]Using unsigned int instead of unsigned short changes behaviour
我正在嘗試K&R的C編程語言中的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。
為什么會這樣? 我錯過了一些微不足道的事情,或者我做了一些非常錯誤的事情導致這種未定義的行為?
當firstIndex
是unsigned int
,在i >= firstIndex
,由於通常的算術轉換, i
被轉換為unsigned int
。 因此,如果i
是負數,它將成為比較表達式中的一個大整數。 當firstIndex
在i >= firstIndex
firstIndex
是unsigned short int
時, firstIndex
被提升為int
並且比較兩個有符號整數。
你可以改變:
for(int i = len-1; i >= firstIndex; i--)
至
for(int i = len-1; i >= (int) firstIndex; i--)
在這兩種情況下都有相同的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.