在阅读K& R的同时,我遇到了整数到字符串的功能。我给它快速阅读,并决定自己实现它,但它不是打印,而是更新字符数组。
这就是我所拥有的
void inttostr(int number, char str[]) {
static int i;
if (number / 10) {
inttostr(number / 10, str);
}
str[i++] = number % 10 + '0';
}
它似乎适用于我给它的少数整数,但我有一些问题。
\0
,那么为什么在使用printf("%s\n", str);
打印时字符串工作正常?我正在使用Xcode。
这是不作业。我只是在学习。
谢谢!
答案 0 :(得分:4)
你是对的,你永远不会写NUL,这是一个错误。
通常,您无需考虑整个解决方案。你必须确保每一步都是正确的。所以在这种情况下,你说:
1。 inttostr(number / 10, str);
将照顾除最后一位数之外的所有数字。
2。然后我将照顾最后一个。
但你可以追踪正在发生的事情。对于例如54321它看起来像:
inttostr(54321, str); // str = ...;
inttostr(5432, str); // str = ...;
inttostr(543, str); // str = ...;
inttostr(54, str); // str = ...;
inttostr(5, str); // str = ...;
str[0] = '5'; // str = "5...";
str[1] = '4'; // str = "54...";
str[2] = '3'; // str = "543...";
str[3] = '2'; // str = "5432...";
str[4] = '1'; // str = "54321...";
请注意,在您编写第一个字符之前没有从任何函数返回时,您将以与调用相反的顺序返回。
...表示您没有NUL终止。另一个问题是您使用的是静态变量,因此您的代码不可重入;这意味着它在某些情况下会中断,包括多线程。
要解决可重入性和NUL问题,您可以执行以下代码。这将创建一个辅助函数,并将当前索引传递给write。
void inttostr_helper(int number, char str[], int *i)
{
if (number / 10) {
inttostr_helper(number / 10, str, i);
}
str[(*i)++] = number % 10 + '0';
str[*i] = '\0';
}
void inttostr(int number, char str[])
{
int i = 0;
inttostr_helper(number, str, &i);
}
编辑:修复了非静态解决方案。
答案 1 :(得分:2)
1,你的编译器(特别是在调试模式下)可能用0填充str。如果用new()分配内存,Unix会这样做 - 但是不要依赖于此,要么将第一个字节设置为\ 0或memset一切都到0
2,纸+铅笔。绘制一个表格,其中每个变量都在顶部,时间在一边。3,先写出最简单,最长的版本,然后再聪明。
答案 2 :(得分:2)
尽管没有必要,但我对使用递归的创造力印象深刻。我认为代码应该删除静态分配的i变量,因为这个变量将通过调用持久化。因此,第二次使用代码中的此函数,例如从main()开始,它不会被启动,并且与前一次调用的值相同。我建议使用返回值如下:
int inttostr(int number, char *str) {
int idx = 0;
if (number / 10) {
idx = inttostr(number / 10, str);
}
str[idx++] = number % 10 + '0';
return idx;
}
答案 3 :(得分:1)
- 我没有明确地在最后包含nul字节\ 0,为什么呢 打印时字符串是否正常工作? with printf(“%s \ n”,str);?
第一次调用函数时,如何声明原始char数组?如果它是一个静态字符数组,那么它将用0填充,这将解释它为什么起作用,否则它只是“运气”
老实说,我不确定是否有人善于递归思考: - )
- 我认为我不擅长递归思考。当我尝试和 在我的脑海中逐步完成这个计划,我 忘记仍在等待的东西 执行。有没有更好的方法 看看内部发生了什么, 帮我学习?
答案 4 :(得分:0)
您是否尝试逐步绘制执行?