我是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);
}
该程序不会运行,有人可以开导我吗? 感谢
答案 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”部分。
假设基数为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
,以便所有数字最终都在同一行。
第一种解决方案是尝试保留大部分原始代码。由于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;
}