转换c

时间:2014-09-06 01:13:11

标签: c functional-programming

我是C的新手,我需要在c中编写一个函数,它将整数转换为指定基数中的字符串并打印出来。

如果输入值为1234(基数为10),则应返回2322(基数为8)。

以下是我目前正在处理的代码结构:

void int2ascii(int value, int base){
    int a=0;
    if (value > base) {
         a = a + int2char(value);     //recursive case
         int2ascii(value/base, base); //base case
    }
    printf("%s\n",a);
 }

该程序不会运行,有人可以开导我吗? 感谢

2 个答案:

答案 0 :(得分:5)

您的计划分析

我首先注意到a被声明为int,但它被传递给printf%s作为格式说明符。 %s指定关联的参数将是一个字符串,a不是。结果将是未定义的行为, 可能导致崩溃

您没有指定int2char()的作用,但我们假设它将数字“数字”转换为相应的char值。考虑到这一点,让我们假设它的实现类似于:

int int2char(int d) {
    return "0123456789abcdefghijklmnopqrstuvwxyz"[d];
}

在您的代码中,您将value传递给int2char()。在我的假设实现中,这将导致数组的越界访问,从而导致未定义的行为。这表示存在逻辑错误, 导致崩溃的另一个可能原因

我注意到,如果value小于base,则a仍为0。可能,即使a小于value,您实际上也要计算base的值。这表示另一个逻辑错误。

基本转换

数字d K d K-1 .. d 0 ,其中每个d i 在(0 ... 9),是Σd i ×10 i 的简写形式。要发现数字N的基数10位,过程为:

  

d i = N / 10 i mod 10

但事实证明,你可以用一些其他基数替换10来计算该基数中数字的数字:

  

d i = N / B i mod B

在您的代码中,以base为单位的递归调用表示计算的第一部分。但是,在计算a时,您错过了计算的“mod”部分。

解决方案1 ​​

假设基数为2到36,并且你的int2char(d)或多或少做了一些事情,如前所述:

void int2ascii(int value, int base){
    int a=0;
    a = a + int2char(value%base);
    if (value > base) {
         int2ascii(value/base, base);
    }
    printf("%c",a);
}

因为您没有将a传递给递归调用,所以您只能使用它来存储要打印的当前数字。因此,移动代码以将a中的值存储在if检查之外,因为您总是希望在最后打印一个合理的值。 a中的数字位于基数base中,因此您需要模数结果才能获得正确的数字值。由于a表示一个字符,因此请更改格式字符串以匹配,并删除\n,以便所有数字最终都在同一行。

解决方案2

第一种解决方案是尝试保留大部分原始代码。由于a已初始化为0,因此额外添加不会使其不正确。但是,由于打印直到最后才会发生,因此根本不需要存储该值,并且可以在您实际想要打印它时进行计算。考虑到这一点,该程序可以简化为:

void int2ascii(int value, int base){
    if (value > base) {
         int2ascii(value/base, base);
    }
    printf("%c",int2char(value%base));
}

答案 1 :(得分:-3)

#include <stdio.h>
#include <limits.h>

char *int2ascii_aux(int n, int base, char *s){
    //base {x| 2 <= x <= 36 }
    static const char *table = "0123456789abcdefghijklmnopqrstuvwxyz";
    if(n){
        *--s = table[n % base];
        return int2ascii_aux(n/base, base, s);
    } else {
        return s;
    }
}

char *int2ascii(int n, int base){
    //base {x| 2<= x <= 36 }
    static char s[sizeof(int)*CHAR_BIT+1];
    if(n <= 0){
        *s = '0';
        return s;
    }
    if(base < 2 ||  base > 36){
        *s = '\0';
        return s;
    }
    return int2ascii_aux(n, base, s + sizeof(s) -1);
}

int main(){
    printf("%s\n", int2ascii(1234, 8));
    return 0;
}