121

在我上大学的时候,我读到了这个auto关键字,随着时间的推移,我实际上忘记了它是什么。它被定义为:

将局部变量定义为具有局部生命周期

我从来没有发现它在任何地方都被使用过,它真的被使用过吗?如果是这样,那么它在哪里使用以及在哪些情况下使用?

4

9 回答 9

153

如果您阅读过IAQ(不常见问题)列表,您就会知道 auto 主要用于定义或声明车辆:

auto my_car;

一直停在户外的车辆:

extern auto my_car;

对于那些缺乏幽默感并且想要“只是事实女士”的人:简短的回答是根本没有任何理由使用auto。唯一允许您使用auto的是已经具有auto存储类的变量,因此您只是指定了无论如何都会发生的事情。尝试auto在没有auto存储类的任何变量上使用将导致编译器拒绝您的代码。我想如果你想获得技术,你的实现不一定是编译器(但它是),理论上它可以在发出诊断后继续编译代码(但它不会)。

kaz的小附录:

还有:

static auto my_car;

这需要根据 ISO C 进行诊断。这是正确的,因为它声明汽车发生故障。诊断是免费的,但关闭仪表板灯将花费您 80 美元。(二十个或更少,如果您从 eBay 购买自己的用于车载诊断的 USB 加密狗)。

上述extern auto my_car还需要诊断,因此它永远不会通过编译器运行,除非由负责停车执法的城市工作人员运行。

如果你在任何代码库中看到很多extern static auto ...,那么你就在一个糟糕的社区;在整个地方转向 Rust 之前立即寻找更好的工作。

于 2010-02-03T14:51:16.157 回答
107

auto是一个修饰符,如static. 它定义了变量的存储类。但是,由于局部变量的默认值是auto,因此您通常不需要手动指定它。

此页面列出了 C 中的不同存储类。

于 2010-02-03T14:23:30.663 回答
57

auto关键字在 C 语言中是无用的。之所以存在,是因为在 C 语言之前存在 B 语言,其中该关键字是声明局部变量所必需的。(B发展成NB,变成C)。

这是B 的参考手册

如您所见,手册中充斥着使用示例auto。之所以如此,是因为没有int关键字。需要某种关键字来表示“这是一个变量的声明”,并且该关键字还指示它是本地的还是外部的(autovs extrn)。如果您不使用其中一个,则会出现语法错误。也就是说,x, y;它本身不是一个声明,而是一个声明auto x, y;

由于在开发语言时必须将用 B 编写的代码库移植到 NB 和 C,因此该语言的较新版本带有一些包袱,以提高向后兼容性,从而减少工作量。在 的情况下auto,程序员不必逐个查找auto并删除它。

从手册中可以明显看出,C 中现在已经过时的“隐式 int”(能够在前面main() { ... }没有任何内容的情况下编写int)也来自 B。这是支持 B 代码的另一个向后兼容功能。函数没有在 B 中指定的返回类型,因为没有类型。一切都是一个词,就像在许多汇编语言中一样。

注意一个函数是如何被声明extrn putchar的,然后是唯一使它成为标识符使用的函数的东西:它在函数调用表达式中使用,如putchar(x),这就是告诉编译器将该无类型单词视为函数指针的原因。

于 2014-06-19T19:19:06.233 回答
29

在 Cauto中是一个关键字,表示变量是块的局部变量。由于这是块范围变量的默认值,因此它是不必要的并且很少使用(我认为我从未见过它在讨论关键字的文本中的示例之外使用)。如果有人能指出auto需要使用 来获得正确的解析或行为,我会很感兴趣。

但是,在 C++11 标准中,auto关键字已被“劫持”以支持类型推断,其中变量的类型可以从其初始值设定项的类型中获取:

auto someVariable = 1.5;   // someVariable will have type double

添加类型推断主要是为了支持在模板中声明变量或从模板函数返回,其中基于模板参数(或在实例化模板时由编译器推导)的类型通常很难手动声明。

于 2010-02-03T15:52:06.717 回答
16

使用旧的 Aztec C 编译器,可以使用命令行开关将所有自动变量转换为静态变量(以提高寻址速度)。

但是在这种情况下,显式声明的变量auto保持原样。(递归函数的必要条件,否则将无法正常工作!)

于 2016-11-16T13:46:00.393 回答
9

auto关键字类似于 Python 中包含分号,它是以前的语言 ( B) 所要求的,但开发人员意识到它是多余的,因为大多数东西都是auto.

我怀疑它是为了帮助从 B 过渡到 C。简而言之,一种用途是为了 B 语言兼容性。

例如在 B 和 80 年代 C 中:

/* The following function will print a non-negative number, n, to
   the base b, where 2<=b<=10.  This routine uses the fact that
   in the ASCII character set, the digits 0 to 9 have sequential
   code values.  */

printn(n, b) {
        extern putchar;
        auto a;

        if (a = n / b)        /* assignment, not test for equality */
                printn(a, b); /* recursive */
        putchar(n % b + '0');
}
于 2017-05-03T23:23:14.647 回答
3

auto只能用于块范围的变量。extern auto int是垃圾,因为编译器无法确定这是使用外部定义还是使用自动定义覆盖 extern(auto 和 extern 也是完全不同的存储持续时间,例如static auto int,这显然也是垃圾)。它总是可以选择以一种方式解释它,而是选择将其视为错误。

有一个特性auto确实提供了,那就是在函数内部启用“一切都是 int”规则。与函数外部不同,由于在文件范围内不存在赋值,因此 wherea=3被解释为定义,这是函数内部的错误,因为显然编译器总是将其解释为对外部变量的赋值而不是定义(即使存在在函数或文件范围内没有前向声明),但是像,或or这样的说明符暗示它是一个定义,编译器将其作为定义,除了没有其他说明符的副作用。因此是隐含的。诚然,int a =3a=3extern int astaticconstvolatileautoautoauto a=3auto int a = 3signed a = 3具有相同的效果,并且unsigned a = 3始终是无符号整数。

另请注意'auto对是否将对象分配给寄存器没有影响(除非某些特定的编译器注意到它,但这似乎不太可能)'

于 2020-03-27T16:23:23.687 回答
1

Auto 关键字是一个存储类(某种决定变量的生命周期和存储位置的技术)示例。它具有一种行为,即由该关键字的 Help 生成的变量的寿命 (lifetime) 仅位于花括号内

{
    auto int x=8;        
    printf("%d",x);  // here x is 8

    { 
        auto int x=3;
        printf("%d",x);  // here x is 3
    }              

    printf("%d",x);  // here x is 8
}          
于 2015-10-20T13:22:14.560 回答
-2

我相信您熟悉 C 中的存储类说明符,它们是“extern”、“static”、“register”和“auto”。“auto”的定义几乎在其他答案中给出,但这里是“auto”关键字的可能用法,我不确定,但我认为它取决于编译器。你看,关于存储类说明符,有一个规则。我们不能对一个变量使用多个存储类说明符。这就是为什么静态全局变量不能被外部化的原因。因此,他们只知道他们的文件。当您进入编译器设置时,您可以启用优化标志以提高速度。编译器优化的方法之一是,它查找没有存储类说明符的变量,然后根据缓存内存的可用性和其他一些因素进行评估,以查看是否应该使用寄存器说​​明符处理该变量。现在,如果我们想优化代码以提高速度,同时知道程序中的特定变量不是很重要,我们甚至不希望编译器将其视为寄存器。我虽然通过放置 auto,编译器将无法将寄存器说明符添加到变量,因为键入“register auto int a;” 或“自动注册int a;” 引发使用多个存储类说明符的错误。综上所述,我认为 auto 可以通过优化来禁止编译器将变量视为寄存器。如果我们想优化代码以提高速度,同时知道程序中的特定变量不是很重要,我们甚至不希望编译器将其视为寄存器。我虽然通过放置 auto,编译器将无法将寄存器说明符添加到变量,因为键入“register auto int a;” 或“自动注册int a;” 引发使用多个存储类说明符的错误。综上所述,我认为 auto 可以通过优化来禁止编译器将变量视为寄存器。如果我们想优化代码以提高速度,同时知道程序中的特定变量不是很重要,我们甚至不希望编译器将其视为寄存器。我虽然通过放置 auto,编译器将无法将寄存器说明符添加到变量,因为键入“register auto int a;” 或“自动注册int a;” 引发使用多个存储类说明符的错误。综上所述,我认为 auto 可以通过优化来禁止编译器将变量视为寄存器。引发使用多个存储类说明符的错误。综上所述,我认为 auto 可以通过优化来禁止编译器将变量视为寄存器。引发使用多个存储类说明符的错误。综上所述,我认为 auto 可以通过优化来禁止编译器将变量视为寄存器。

这个理论不适用于 GCC 编译器,但是我没有尝试过其他编译器。

于 2020-07-22T08:07:40.797 回答