在我的大学时代,我读到了auto
关键字,随着时间的推移,我实际上忘记了它是什么。它被定义为:
将局部变量定义为具有 当地生活
我从未发现它在任何地方都被使用过,它是否真的被使用过,如果是这样,那么它在哪里使用?在哪些情况下?
答案 0 :(得分:114)
如果您阅读了IAQ(不常见问题)列表,您就会知道auto主要用于定义或声明车辆:
auto my_car;
一直停在户外的车辆:
extern auto my_car;
对于那些缺乏幽默感并想要“只是事实女士”的人:简短的回答是,根本没有任何理由可以使用auto
。您被允许使用auto
的唯一时间是使用已有auto
存储类的变量,因此您只需指定可能会发生的事情。尝试在任何没有auto
存储类的变量上使用auto
将导致编译器拒绝您的代码。我想如果你想获得技术,你的实现不一定是编译器(但它是),理论上它可以在发出诊断后继续编译代码(但它不会)。
kaz的小附录:
还有:
static auto my_car;
需要根据ISO C进行诊断。这是正确的,因为它声明汽车已经损坏。诊断是免费的,但关闭仪表板灯将花费你八十美元。 (二十或更少,如果你从eBay购买自己的USB加密狗进行车载诊断)。
前面提到的extern auto my_car
也需要诊断,因此除了负责停车执法的城市工作人员之外,它永远不会通过编译器运行。
如果你在任何代码库中看到很多extern static auto ...
,那么你就是一个糟糕的社区;在整个地方转向Rust之前,立即寻找更好的工作。
答案 1 :(得分:77)
auto
是static
之类的修饰符。它定义变量的存储类。但是,由于局部变量的默认值为auto
,因此通常不需要手动指定它。
This page列出了C中的不同存储类。
答案 2 :(得分:36)
{C}语言中auto
关键字无用。它存在,因为在C语言之前存在一种B语言,其中该关键字是声明局部变量所必需的。 (B被发展成为NB,后来成为C)。
正如您所看到的,本手册充满了使用auto
的示例。之所以如此,是因为没有int
个关键字。需要某种关键字来表示“这是变量的声明”,该关键字还表示它是本地还是外部(auto
与extrn
)。如果您不使用其中一个,则会出现语法错误。也就是说,x, y;
本身不是声明,但auto x, y;
是。
由于用B语言编写的代码库必须在开发语言时移植到NB和C语言,因此语言的较新版本带来了一些包袱,以提高后向兼容性,从而减少工作量。在auto
的情况下,程序员不必追捕auto
的每次出现并将其删除。
从手册中可以明显看出,C中现在过时的“隐式int”错误(能够在前面没有任何main() { ... }
编写int
)也来自B.这是另一个向后兼容的特性支持B代码。函数没有在B中指定的返回类型,因为没有类型。一切都是一个词,就像许多汇编语言一样。
注意如何将函数声明为extrn putchar
,然后唯一使它成为标识符的使用的函数:它用于函数调用表达式,如{{1}这就是告诉编译器将该无类型字视为函数指针的原因。
答案 3 :(得分:22)
在C auto
中是一个关键字,表示变量是块的本地变量。因为这是块范围变量的默认值,所以它是不必要的并且很少使用(我不认为我在讨论关键字的文本中使用它之外的例子)。如果有人能够指出需要使用auto
来获得正确的解析或行为,我会感兴趣。
但是,在C ++ 11标准中,auto
关键字已被“劫持”以支持类型推断,其中变量的类型可以从其初始化程序的类型中获取:
auto someVariable = 1.5; // someVariable will have type double
正在添加类型推断主要是为了支持在模板中声明变量或从模板函数返回,其中基于模板参数的类型(或者在实例化模板时由编译器推导出来)通常很难手动声明。
答案 4 :(得分:8)
使用旧的Aztec C编译器,可以使用命令行开关将所有自动变量转换为静态变量(以提高寻址速度)。
但是在这种情况下,用auto
显式声明的变量保持原样。 (必须用于递归函数,否则将无法正常工作!)
答案 5 :(得分:6)
auto
关键字类似于在Python中包含分号,它是先前语言(B
)所要求的,但开发人员意识到它是多余的,因为大多数事情都是auto
。
我怀疑它是为了帮助从B到C的转换。简而言之,一个用途是B语言的兼容性。
例如在B和80s 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) {
extrn putchar;
auto a;
if (a = n / b) /* assignment, not test for equality */
printn(a, b); /* recursive */
putchar(n % b + '0');
}
答案 6 :(得分:1)
stackbox run
仅可用于块作用域变量。 auto
是垃圾,因为编译器无法确定它是使用外部定义还是使用自动定义覆盖extern(而且auto和extern的存储持续时间完全不同,例如extern auto int
,这是也是垃圾)。它总是可以选择以一种方式解释它,而是选择将其视为错误。
static auto int
确实提供了一个功能,该功能使函数中的“一切都是整数”规则。与函数外部不同,auto
被解释为定义a=3
,因为在文件作用域中不存在赋值,int a =3
是函数内部的错误,因为显然编译器总是对其进行解释作为对外部变量(而不是定义)的赋值(即使函数或文件范围中没有a=3
前向声明),而是extern int a
,static
之类的说明符, const
或volatile
暗示它是一个定义,编译器将其视为一个定义,除了auto
没有其他说明符的副作用。因此,auto
是隐式auto a=3
。诚然,auto int a = 3
具有相同的效果,signed a = 3
始终是无符号整数。
还请注意'unsigned a = 3
对对象是否将分配给寄存器没有影响(除非某些特定的编译器对此有所注意,但这似乎不太可能)'
答案 7 :(得分:0)
Auto关键字是一个存储类(某种决定变量和存储位置生命周期的技术)示例。它具有一种行为,通过该行为,该关键字的帮助所产生的变量具有生命周期(生命周期)仅驻留在花括号中
{
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
}
答案 8 :(得分:-2)
auto
说你不希望它是register
,这很好。
但是它通常是无用的,因为编译器会将register
置于何时
它既没有被使用,也没有被认为是最优的,而且它很少会错误地认为,但它常常会错过register
是最优的。
答案 9 :(得分:-2)
我确定您熟悉C中的存储类说明符,它们是“ extern”,“ static”,“ register”和“ auto”。 其他答案中几乎给出了“ auto”的定义,但是我不确定“ auto”关键字的可能用法,但我认为它取决于编译器。 您会看到,关于存储类说明符,有一条规则。我们不能为变量使用多个存储类说明符。这就是为什么静态全局变量不能被外部化的原因。因此,它们仅在文件中已知。 转到编译器设置时,可以启用速度优化标记。编译器优化的一种方法是,它在没有存储类说明符的情况下查找变量,然后根据高速缓存的可用性和其他一些因素进行评估,以查看是否应使用寄存器说明符来处理该变量。现在,如果我们想优化代码以提高速度,同时又知道程序中的特定变量不是很重要,又不想让编译器甚至将其视为寄存器,该怎么办?我虽然输入了auto,但是由于键入“ register auto int a;”,编译器将无法向变量添加寄存器说明符。或“自动注册int a”;引发使用多个存储类说明符的错误。 综上所述,我认为auto可以禁止编译器通过优化将变量视为寄存器。
该理论不适用于GCC编译器,但是我没有尝试过其他编译器。