/* 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');
}
auto只能用于块作用域的变量。extern auto int是垃圾,因为编译器无法确定这是否使用了外部定义,或者是否用auto定义覆盖extern(auto和extern是完全不同的存储持续时间,就像static auto int一样,这显然也是垃圾)。它总是可以选择以一种方式解释它,而是选择将其视为错误。 auto确实提供了一个特性,那就是在函数内部启用“一切都是int”规则。在函数外部,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始终是无符号整型。 还要注意' auto对是否将对象分配给寄存器没有影响(除非某些特定的编译器注意到它,但这似乎不太可能)'
我相信你熟悉C中的存储类说明符,它们是“extern”,“static”,“register”和“auto”。“auto”的定义在其他答案中已经给出了很多,但这里有一个我不确定的“auto”关键字的可能用法,但我认为它依赖于编译器。你看,关于存储类说明符,有一个规则。我们不能为一个变量使用多个存储类说明符。这就是为什么静态全局变量不能被外部化的原因。因此,它们仅对其文件是已知的。当你转到你的编译器设置时,你可以启用优化标志来提高速度。编译器优化的方法之一是,它查找没有存储类说明符的变量,然后基于高速缓存内存的可用性和一些其他因素进行评估,以确定是否应该使用寄存器说明符来处理该变量。现在,如果我们想优化代码的速度,同时知道程序中的某个特定变量不是很重要,我们甚至不希望编译器将其视为寄存器,那该怎么办?我认为通过输入auto,编译器将无法向变量添加寄存器说明符,因为输入“register auto int a;“OR“auto register int a;“引发使用多个存储类说明符的错误。总而言之,我认为auto可以通过优化来禁止编译器将变量视为寄存器。 这个理论不适用于GCC编译器,但我没有尝试过其他编译器。
9条答案
按热度按时间kknvjkwl1#
如果你读过IAQ(不常见问题)列表,你就会知道auto主要用于定义或声明车辆:
字符串
经常停在户外的车辆:
型
对于那些缺乏任何幽默感,想要“只是事实女士”的人:简短的回答是,根本没有任何理由使用
auto
。唯一允许使用auto
的情况是已经有auto
存储类的变量,所以你只是指定了一些无论如何都会发生的事情。尝试在任何没有auto
存储类的变量上使用auto
将导致编译器拒绝您的代码。我想如果你想得到技术,你的实现不必是一个编译器(但它是),理论上它可以在发出诊断后继续编译代码(但它不会)。kaz的小齿顶高:
还有:
型
这需要根据ISO C进行诊断。这是正确的,因为它宣布汽车坏了。诊断是免费的,但是关掉 Jmeter 板上的灯要花八十美元。(如果您从eBay购买自己的USB加密狗用于车载诊断,则为20或更少)。
前面提到的
extern auto my_car
也需要一个诊断程序,因此除了负责停车执法的城市工作人员之外,它永远不会通过编译器运行。如果您在任何代码库中看到大量的
extern static auto ...
,那么您就处在一个糟糕的环境中;在整个地方变成Rust之前,立即寻找更好的工作。xsuvu9jc2#
auto
是一个类似于static
的修饰符。它定义了变量的存储类。但是,由于局部变量的默认值是auto
,因此通常不需要手动指定它。This page列出了C中不同的存储类。
ct2axkht3#
auto
关键字在C语言中是无用的。它在那里是因为在C语言之前存在一种B语言,在这种语言中,该关键字是声明局部变量所必需的。(B发展成NB,NB变成C)。这里是reference manual for B。
如您所见,手册中充斥着使用
auto
的示例。这是因为没有int
关键字。需要某种关键字来表示“这是一个变量的声明”,并且该关键字还指示它是本地还是外部(auto
与extrn
)。如果不使用其中一个,则会出现语法错误。也就是说,x, y;
本身不是声明,但auto x, y;
是。由于用B语言编写的代码库必须在语言开发时移植到NB和C,因此该语言的新版本为改进向后兼容性带来了一些负担,这些负担转化为更少的工作。在
auto
的情况下,程序员不必搜索auto
的每个出现并将其删除。从手册中可以明显看出,现在已经过时的C中的“隐式int”cruft(能够在前面不使用任何
int
的情况下编写main() { ... }
)也来自B。这是支持B代码的另一个向后兼容特性。函数没有在B中指定的返回类型,因为没有类型。一切都是一个词,就像许多汇编语言一样。注意一个函数可以被声明为
extrn putchar
,然后唯一使它成为标识符的函数的是:它被用在像putchar(x)
这样的函数调用表达式中,这就是告诉编译器把这个无类型的字当作函数指针的原因。v8wbuo2f4#
在C语言中,
auto
是一个关键字,表示一个变量是块的局部变量。因为这是块作用域变量的默认值,所以它是不必要的,而且很少使用(我想我从来没有见过它在讨论关键字的文本中的示例之外使用)。如果有人能指出需要使用auto
来获得正确的解析或行为的情况,我会很感兴趣。然而,在C++11标准中,
auto
关键字被“劫持”以支持类型推断,其中变量的类型可以从其初始化器的类型中获取:字符串
添加类型推断主要是为了支持在模板中声明变量或从模板函数返回,其中基于模板参数的类型(或当模板示例化时由编译器推导出的类型)通常手动声明非常痛苦。
4c8rllxm5#
使用旧的阿兹特克C编译器,可以使用命令行开关将所有自动变量转换为静态变量(以提高寻址速度)。
但是在这种情况下,用
auto
显式声明的变量保持原样。(这是递归函数的必备功能,否则将无法正常工作!)ubby3x7f6#
auto
关键字类似于Python中包含的分号,它是以前的语言(B
)所必需的,但开发人员意识到它是多余的,因为大多数东西都是auto
。我怀疑它是为了帮助从B到C的过渡而留在里面的。简而言之,一个用途是B语言兼容性。
例如,在B和80年代C:
字符串
nwlqm0z17#
auto
只能用于块作用域的变量。extern auto int
是垃圾,因为编译器无法确定这是否使用了外部定义,或者是否用auto定义覆盖extern(auto和extern是完全不同的存储持续时间,就像static auto int
一样,这显然也是垃圾)。它总是可以选择以一种方式解释它,而是选择将其视为错误。auto
确实提供了一个特性,那就是在函数内部启用“一切都是int”规则。在函数外部,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
始终是无符号整型。还要注意'
auto
对是否将对象分配给寄存器没有影响(除非某些特定的编译器注意到它,但这似乎不太可能)'iezvtpos8#
Auto关键字是一个存储类(某种决定变量生存期和存储位置的技术)示例。它有一个行为,通过该行为,由该关键字的Help创建的变量仅驻留在花括号内
字符串
b0zn9rqh9#
我相信你熟悉C中的存储类说明符,它们是“extern”,“static”,“register”和“auto”。“auto”的定义在其他答案中已经给出了很多,但这里有一个我不确定的“auto”关键字的可能用法,但我认为它依赖于编译器。你看,关于存储类说明符,有一个规则。我们不能为一个变量使用多个存储类说明符。这就是为什么静态全局变量不能被外部化的原因。因此,它们仅对其文件是已知的。当你转到你的编译器设置时,你可以启用优化标志来提高速度。编译器优化的方法之一是,它查找没有存储类说明符的变量,然后基于高速缓存内存的可用性和一些其他因素进行评估,以确定是否应该使用寄存器说明符来处理该变量。现在,如果我们想优化代码的速度,同时知道程序中的某个特定变量不是很重要,我们甚至不希望编译器将其视为寄存器,那该怎么办?我认为通过输入auto,编译器将无法向变量添加寄存器说明符,因为输入“register auto int a;“OR“auto register int a;“引发使用多个存储类说明符的错误。总而言之,我认为auto可以通过优化来禁止编译器将变量视为寄存器。
这个理论不适用于GCC编译器,但我没有尝试过其他编译器。