【问题标题】:atoi is a standard function. But itoa is not. Why?atoi 是一个标准函数。但 itoa 不是。为什么?
【发布时间】:2012-04-15 14:07:57
【问题描述】:

为什么会有这种区别?我遇到了可怕的问题,假设itoastdlib.h 中,最后将itoa 的自定义版本与不同的原型链接起来,从而产生了一些疯狂的错误。

那么,为什么itoa 不是标准函数?它出什么问题了?为什么标准偏向其孪生兄弟atoi

【问题讨论】:

  • atoi 是历史记录,itoa 不是。无论如何,你不应该真的使用atoistrto(u)l(l) 是你应该使用的。对于另一个方向,s(n)printf.
  • 由于itoa 不是标准函数,您能否包含您要讨论的itoa 函数的接口契约应该是什么? (这样做可能会回答您的问题。)
  • @CharlesBailey 我只是好奇为什么标准包括 atoi 而不是 itoa
  • @Stacker:你心里有没有特别的itoa
  • @CharlesBailey 类似this

标签: c function posix standards itoa


【解决方案1】:

没有itoa 曾经被标准化,因此要将其添加到标准中,您需要一个令人信服的理由和一个良好的界面来添加它。

我见过的大多数itoa 接口要么使用具有可重入性和生命周期问题的静态缓冲区,要么分配调用者需要释放的动态缓冲区,要么要求用户提供缓冲区,这使得界面没有更好比sprintf.

【讨论】:

  • 使用传入缓冲区的 itoa() 可能是对 s(n)printf() 的巨大胜利,因为该库的特定部分没有使用任何其他内容(printf() 系列中没有任何内容) .这不是将 itoa() 放在标准 C 库中的原因,但它是更喜欢它而不是更重的东西的原因。
  • @JulieinAustin:为什么这是一场巨大的胜利?没错,您不必解析两个字符的格式字符串,但我不认为这是一个 huge 胜利。
  • 也可以避免使用 printf() 系列附带的所有其他解析函数。记住——除了解析格式字符串之外,生活中还有其他事情。比如,内存占用。
  • 我想@JulieinAustin 正在为严格受限的目标环境(例如设备固件)进行编码。这不是 FOSS 的常用用途,但它是 C 的一个重要应用领域。有时在这些环境中,您不允许链接到任何 *printf 函数。
  • @Spike0xff 猜对了——我做了很多编码,其中 64K 仍然被认为是“巨大的”。我写的最后一段 C 编译为 15K 并且使用了不到 2K 的 RAM。这是一件好事,因为该部件有 28K 的 I 空间和 2K 的 D 空间。
【解决方案2】:

“itoa”函数必须返回一个字符串。由于字符串不是一流的对象,调用者必须传递一个缓冲区 + 长度,并且该函数必须有某种方式来指示它是否用完空间。当你走到那一步时,你已经创建了与 sprintf 足够相似的东西,因此不值得复制代码/功能。 “atoi”函数的存在是因为它比完整的“scanf”调用更简单(并且可以说更安全)。 “itoa”函数的不同之处不足以值得。

【讨论】:

  • 并非如此。多年来,许多开发人员在代码中包含了类似 itoa() 的例程。最大缓冲区大小是有界的 - 6 字节和一个备用的 NUL 用于 16 位 boxen,11 加上一个备用用于 32 位 boxen。我在一个数据采集固件中使用 itoa() 函数来格式化包含版本和状态信息的文本字符串。在那个实现中,我确实传递了一个指针,但我看到其他人的缓冲区是静态的。最好的解释是,就像标准一样,有很多不同的 itoa() 实现可供选择!!!
  • @JulieinAustin - 我并不是说它们不存在,只是它们没有标准化。您的描述有助于说明原因。缓冲区大小因机器的寄存器大小而异。 C 标准委员会远离此类特定于硬件的细节。一个标准化的函数必须有一个一致的接口并且在任何平台上都一样工作,而做到这一点的唯一实用方法是重新发明printf()的大部分内容。
  • 我在回复您的断言,即该函数将 =have= 执行各种操作。它确实没有,并且可以使用适当数量的 weasel-words 轻松指定实现,以解决字长的差异。我的意思是,对于任何给定的字长,都有一个易于理解的、有限数量的存储字符,需要这些字符来表示该字长的所有可能的整数值。 TL;DR - 它可以并且已经比您建议的更容易和更一致地实施。
【解决方案3】:

itoa 函数不是标准的,原因可能是它没有一致的定义。不同的编译器和库供应商已经推出了它的细微不同的版本,可能是作为对atoi 的补充的发明。

如果一些非标准功能被供应商广泛提供,那么标准的工作就是编纂它:基本上是在标准中添加对现有功能的描述。如果函数具有或多或少一致的参数约定和行为,这是可能的。

因为itoa 的多种风格已经存在,所以不能将这样的函数添加到 ISO C 中。无论描述什么行为都会与某些实现不一致。

itoa 曾以如下形式存在:

void itoa(int n, char *s); /* Given in _The C Programming Language_, 1st ed. (K&R1) */

void itoa(int input, void (*subr)(char)); /* Ancient Unix library */

void itoa(int n, char *buf, int radix);
char *itoa(int in, char *buf, int radix);

Microsoft 在其 Visual C 运行时库中以更改后的名称提供它:_itoa

C 实现不仅历史上在不同的定义下提供了它,C 程序还为自己提供了一个名为 itoa 的函数,这是可能发生冲突的另一个来源。

基本上,itoa 标识符在作为外部名称或宏的标准化方面具有“放射性”。如果此类函数已标准化,则必须使用不同的名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-27
    • 2016-08-18
    • 2016-11-24
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    相关资源
    最近更新 更多