6

这是一个类,所以它必须使用递归,我已经迭代地编写了一个工作代码,但我无法让它在递归中工作,我真的迷路了。我已经为此工作了一周。任何指导或建议都会非常有帮助。

这是我的功能,我需要将十六进制作为字符指针并输出它对应的十进制。我经常遇到堆栈溢出内存分配运行时错误,任何人都可以找出问题所在并引导我朝着正确的方向前进吗?

 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;
  }
}
4

5 回答 5

7

我没有编译它,但第一眼告诉我对应的行应该是:

return hexToDecimal(hex, offset-1, power+1) +  hexNum * (int) pow(16,power-1);    

因为在您的情况下,您称自己为无限(被称为偏移量 6,如果您传递偏移量 - 它仍然会传递 6,因为它在为函数提供值后会递减)。

此外,后增量将为您pow(16,power)稍后在同一表达式中的调用提供未定义的行为,因为(再次以 power=6 为例),它可能是pow(16,6)pow(16,7)取决于编译器。

除此之外,还有风险,当转换为 int 时 pow() 会给你错误(向下舍入)值(结果可能是 pow(16,2) 返回 255.9999999,你最终得到 (int)255,有在 stackoverflow 上有充分的证据和解决方案,只需搜索 pow)。

编辑(回复评论):

最后,介绍神奇的 printf 调试器:

int hexToDecimal(const char *hex, int offset, int power){
  if(offset >= 0){
    char hexChar = *(hex+offset);
    int hexNum, 
        recursed;

    if( isalpha(hexChar) ) {
      hexChar = toupper(hexChar);
      hexNum = hexChar - asciiCharOffset;
    } 
    else { 
      hexNum = hexChar - asciiIntOffset;
    }   
    recursed= hexToDecimal(hexNum, offset-1, power+1); 

    printf("%d + %d * %d\n", recursed, hexNum, (int)pow(16,power-1));

    return recursed +  hexNum * (int)pow(16,power-1); 

  } else {
     return 0;
  }
}
于 2013-06-13T22:22:28.550 回答
1

您在这里使用后增量:

  return hexToDecimal(hex, offset--, power++) 

后递增(和后递减)将递增/递减变量(即它实际上会改变 offsetand power),但 inc/dec 将在评估变量后发生。

IE:

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在您无意修改参数时制作参数。这样,编译器可以帮助您捕获许多常见错误。

于 2013-06-13T22:23:13.630 回答
1

在函数参数中使用预减量。在参数中使用 --offset。如果你使用偏移量——那么偏移量的初始值被传递给函数,然后偏移量减少。

于 2013-06-13T22:26:31.803 回答
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;
}
于 2013-06-13T22:26:13.900 回答
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来处理更大的十六进制数字。

于 2013-06-13T22:39:28.497 回答