为什么命令行参数计数变量(传统的“argc”)是'int'而不是'unsigned int'?这有技术原因吗?
在尝试删除所有已签名的无符号比较警告时,我总是忽略它,但从未理解为什么它是这样的。
答案 0 :(得分:51)
原始C语言是这样的,即默认任何变量或参数被定义为int ,这可能是另一个因素。换句话说,你可以:
main(argc, char* argv[]); /* see remark below... */
而不是
int main(int argc, char *argv[]);
编辑:有效地,正如Aaron提醒我们的那样,原始语法会像
一样 main(argc, argv) char **argv {... }
由于“原型”仅在稍后介绍。这大概是在每个人都至少记录了至少10个小时后追逐微妙(而不是那么微妙)类型相关的错误
答案 1 :(得分:30)
有几个原因:
unsigned
关键字或无符号整数类型 int
类型,因为这是默认值。int
在某种意义上更重要。一切都是一个int。 C部分来自一种甚至没有类型的语言。每个可变数据都是word
,这是int
最初使用的内容。更新: Jason S要求提供来源。我认为你可以通过dmr在线上的论文挖掘所有这些(除了“无关紧要”): The Development of the C Language。您可能需要在通常的位置查找早期语言BCPL和B.
答案 2 :(得分:12)
因为C是旧的,并且它从一开始就是这样设计的。现在改变它已经太晚了。
答案 3 :(得分:11)
Here's用dmr自己的话来说就是C编程语言的历史。它没有明确说明(至少不是我给它的快速浏览),但最早的C版本不支持无符号类型。 mjv关于int
的隐式输入的观点也是相关的。
修改强>
贝尔实验室链接已暂停一段时间:here's指向同一篇论文的备用链接。
答案 4 :(得分:7)
另一个原因可能是无符号类型可能不便于迭代。例如,此代码段向下迭代:
for (size_t i = SIZE - 1; i >= 0; --i)
...
事实上,这是一个错误。当我在最后一次迭代中达到0时,它将直接进入4294967295(在32位机器上)并且循环不会终止。
出于这个原因,我个人觉得简单的int更方便迭代。使用整数时,将for
循环从倒计时切换到倒计时时,您不必特别小心。
答案 5 :(得分:6)
Google C++ Style Guide建议永远不要使用unsigned int
类型,除非您正在处理实际的位模式。他们的理由也适用于C.快速摘要行:
... C的类型提升方案导致无符号类型的行为与预期的不同。 ...不要使用无符号类型。
这可能不是C的原始创作者的想法,但谁知道呢
答案 6 :(得分:5)
作为您的警告问题的解决方案,您可以执行以下操作来禁止警告:
const unsigned int uargc = (unsigned int) argc;
答案 7 :(得分:4)
由于Java中没有未签名的类型,因此将来更容易将C程序移植到Java是一种有先见之明的设计决策。
答案 8 :(得分:3)
main()
的声明是在将无符号类型添加到语言之前定义的 - 请参阅DMR的“Primeval C”页面。添加无符号时更改为时已晚。
答案 9 :(得分:1)
我看到它看起来很奇怪:argc
不应该是负面的!但请以这种方式看待:int
和unsigned int
覆盖您接受的值范围(如果您有2 ^ 31个命令行参数,则表示您遇到问题)和int
输入的时间更短。
采访拼图问题:如果C与unsigned
一起使用,键入unsigned int argc
会占用多少个键盘?
答案 10 :(得分:0)
通过将其设置为int,范围限制在1和INT_MAX之间(包括1和INT_MAX)。这通常意味着没有意外的演员或别名会使其超出无意中的环绕范围。它还允许实现使用整个负数和0范围用于特定于系统的方案。
好的,我刚刚做到了。真正的原因是它只是一个原始的C语言开发人员做出的任意决定,直到现在还没有人真正想到它。 :)
答案 11 :(得分:0)
一个简单的问题:您是否期望超过2个 31 (或甚至超过2个 15 )命令行参数?我怀疑大多数操作系统可以处理那么多。
答案 12 :(得分:-2)
我认为它的设计与C兼容,而在C语言中,人们对签名/未签名的正确性并不十分关注。