c - 在尝试编写 atoi 的递归版本时,itoa(n /10, s) 的含义是什么,为什么建议避免使用 static int i = 0?
问题描述
如果我的问题很模糊,我很抱歉,因为它没有上下文。所以我试图解决一个问题:编写函数 itoa(i) 的递归版本,它将整数 i 转换为字符串。
当我不知道如何解决它时,我开始在网上寻找解决方案,我遇到了一些通常使用这条线的解决方案:itoa(n/10, s);。例如,来自这个 StackOverflow 问题:itoa recursively。我无法理解它对我有什么影响。
所以我继续寻找更多解决方案,我找到了一个真正有效的解决方案,程序如下所示:
#include <stdio.h>
char *itoa(int n, char s[]);
int main()
{
char number[100];
printf("-90 to string = %s\n", itoa(-90, number));
return 0;
}
char *itoa(int n, char s[])
{
static int i = 0;
if (n < 0) {
s[i++] = '-';
n = -n; /* does not work for largest negative number in two complement */
}
if (n / 10)
itoa(n /10, s);
s[i++] = n % 10 + '0';
s[i] = '\0';
return s;
}
问题是,根据我在其他网站上找到的解决方案,人们说我们应该避免使用静态 int i。我没有读到为什么我们应该这样做,因为我不知道静态是如何工作的,所以我不知道这个程序是否很好或需要改进。
解决方案
您的功能几乎是正确的,即用于递归方法。如果您要将数字向后解析为字符串,那是对的。否则,我只是做了几个修复。
对于将数字解析为字符串,正在解析的数字是从右数到左数,因为其余的是正在使用的数字。因此,当将它们存储到字符串中时,我们需要从高索引到低索引。如果我们使用余数进行解析,我们将不知道正在解析的数字的长度。因此,在大多数解析情况下,字符串或字符数组的开头会有一些额外的空格。
对于使用静态 i,您可以传递它的一个版本,但它会使其更难使用,因为您需要知道始终必须在 11 处传递 i。“i”位于 11,因为 int 的最大位数是 10(digits) + 1 符号,第 12 个不被“i”计算的字符是空字符。为了使函数更容易使用,我将第三个参数配置为空指针。但是,不要将实际指针传递给它,而是将其传递给 NULL。当它看到 NULL 作为第三个参数时,它就知道,那是第一次调用。
#include <stdio.h>
#include <string.h>
char *itoa(int n, char s[], void * );
int main()
{
char number[100] = {0};
printf("-90 to string = %s\n", itoa(154, number, NULL));
printf("-15 to string = %s\n", itoa(-15, number, NULL));
printf("-2147483648 to string = %s\n", itoa(-2147483648, number, NULL));
return 0;
}
// The reason why I pass a void pointer is because
// instead of passing the value is because it easier to use function without needing to know that the string have to go from right left.
// When you first call it just use NULL as the third parameter. Anything else can ruin it.
char *itoa(int n, char s[], void * firstCall )
{
static int i;
if ( firstCall == NULL ) {
i = 11;
s[11] = 0;
}
int neg = 0;
if (n < 0) {
if ( n == -2147483648 ) {
strcpy(s, "-2147483648");
return s;
}
neg=1;
n = -n; /* does not work for largest negative number in two complement */
}
s[--i] = (n % 10) ^ 48;
if ( n / 10 ) itoa(n / 10, s, s);
if ( neg == 1 ) s[--i] = '-';
return &s[i];
}
推荐阅读
- c# - HttpContext.Current.Request.Files.Count 每次都返回 null。我想将文件上传到服务器中的文件夹
- flutter - Flutter 设计模式:有什么最值得推荐的吗?
- python - 如何抑制来自 jaydebeapi 罐子的日志
- javascript - 循环和测试正则表达式对象的最佳和最有效的方法是什么
- tensorflow.js - 将 tf_op_layers 转换为 tfjs
- javascript - 如何从单独的文件中以角度重用或调用函数?
- python - 在Python中将整数转换为日期格式MDD到'M / DD'
- javascript - Javascrip 的 Jinja2 变量给出了 Undefined 类型的对象
- verilog - 如果将默认案例添加到完整案例语句中会发生什么?
- java - 添加 Firebase Analytics 时 Android 无法构建