这是一个类,所以它必须使用递归,我已经迭代地编写了一个工作代码,但我不能让它在递归中工作,我真的迷路了。我已经为此工作了一个星期。任何指导或建议都会非常有用。
这是我的函数,我需要将十六进制作为char指针并输出相应的十进制数。我经常遇到堆栈溢出或内存分配运行时错误,任何人都可以识别出错误并引导我朝着正确的方向前进吗?
int hexToDecimal(const char *hex, int offset, int power){
if(offset >= 0){
hexChar = *(hex+offset);
if( isalpha(hexChar) ) {
hexChar = toupper(hexChar);
hexNum = hexChar - asciiCharOffset;
} else {
hexNum = hexChar - asciiIntOffset;
}
return hexToDecimal(hex, offset--, power++) + hexNum * (int)pow(16,power);
} else {
return 0;
}
}
答案 0 :(得分:7)
我没有编译它,但第一眼就告诉我相应的行应该是:
return hexToDecimal(hex, offset-1, power+1) + hexNum * (int) pow(16,power-1);
因为在你的情况下,你无限地称呼自己(被调用,假设偏移6,如果你传递偏移 - 它仍然会传递6,因为它会在给函数赋值后减少)。 / p>
此外,后增量将为您在同一表达式中稍后调用pow(16,power)
提供未定义的行为,因为(再次以power = 6为例),它可能是pow(16,6)
或{ {1}}取决于编译器。
除此之外,还存在风险,即pow()在转换为int时会给出错误(向下舍入)值(可能会发现pow(16,2)返回255.9999999而你最终得到(int) 255,stackoverflow上有足够的证据和解决方案,只需搜索pow)。
编辑(回复评论):
最后,介绍了神奇的printf调试器:
pow(16,7)
答案 1 :(得分:1)
你在这里使用后增量:
return hexToDecimal(hex, offset--, power++)
后递增(和后递减)将递增/递减变量(即它实际上更改 offset
和power
),但是inc / dec将在评估变量之后发生。
即:
int i = 5;
std::cout << "i = " << i; // prints 'i = 5'
std::cout << "\ni = " << i++; // still prints 'i = 5' and then changes i to be 6
std::cout << "\ni = " << i; // prints 'i = 6'
您实际上并不想修改offset
和power
- 您希望将这些值的其他值传递给下一个hexToDecimal
来电。
如果你制作方法参数const
,你可以捕捉到这些错误,即:
int hexToDecimal(const char*hex, const int offset, const int power);
我建议您在无意修改参数时const
。这样编译器可以帮助您捕获许多常见错误。
答案 2 :(得分:1)
在函数参数中使用predecrement。在参数中使用--offset。 如果你使用offset--则将offset的初始值传递给函数,然后减少offset。
答案 3 :(得分:0)
这是我在很久以前写过的一篇......它可能不是最好或最快的方法,可能会使用一些错误检查,但我会将其作为练习留给读者......
long GetValue(const char *pszStrVal)
{
long Retval = 0;
try {
char *p = (char*)pszStrVal;
if(p == NULL) return 0;
if(strstr(p, "0x")) {
p++;p++;
long x = strlen(p);
long pval = 1 << ((x-1)*4);
for(int y = 0;y < x;y++,pval = (pval >> 4))
{
int digit = 0;
switch(p[y])
{
case 'A':
case 'a':
digit = 10;
break;
case 'B':
case 'b':
digit = 11;
break;
case 'C':
case 'c':
digit = 12;
break;
case 'D':
case 'd':
digit = 13;
break;
case 'E':
case 'e':
digit = 14;
break;
case 'F':
case 'f':
digit = 15;
break;
default:
digit = p[y] - 0x30;
}
Retval += (pval * digit);
}
} else {
Retval = atoi(p);
}
}
catch(...)
{
Retval = 0;
}
return Retval;
}
答案 4 :(得分:0)
这是一个使用第二个递归函数调用的简单解决方案。希望它能帮助你调试你的:
#include <stdio.h>
#include <ctype.h>
int h2d_rec(const char *hex, int d);
int h2d(const char *hex) {
return h2d_rec(hex, 0);
}
int h2d_rec(const char *hex, int d) {
char hexChar = *hex;
if (0==hexChar) {
return d;
}
int charNum;
if (isalpha(hexChar)) {
charNum = 10 + toupper(hexChar) - 'A';
} else {
charNum = hexChar - '0';
}
// Note d<<4 is the same as 16*d
return h2d_rec(hex+1, (d<<4) + charNum);
}
int main(int argc, const char **argv) {
const char *hex = "FF";
if (1<argc) {
hex = argv[1];
}
printf("%s in decimal is %d\n", hex, h2d(hex));
}
您可能希望使用long
来处理更大的十六进制数。