C auto关键字在哪里使用?

kgqe7b3p  于 2023-08-03  发布在  其他
关注(0)|答案(9)|浏览(128)

在我的大学时代,我读到了auto关键字,随着时间的推移,我实际上忘记了它是什么。定义为:
将局部变量定义为具有局部生存期
我从来没有发现它在任何地方被使用,它真的被使用了吗?如果是的话,那么它在哪里被使用,在哪些情况下被使用?

kknvjkwl

kknvjkwl1#

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

auto my_car;

字符串
经常停在户外的车辆:

extern auto my_car;


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

static auto my_car;


这需要根据ISO C进行诊断。这是正确的,因为它宣布汽车坏了。诊断是免费的,但是关掉 Jmeter 板上的灯要花八十美元。(如果您从eBay购买自己的USB加密狗用于车载诊断,则为20或更少)。
前面提到的extern auto my_car也需要一个诊断程序,因此除了负责停车执法的城市工作人员之外,它永远不会通过编译器运行。
如果您在任何代码库中看到大量的extern static auto ...,那么您就处在一个糟糕的环境中;在整个地方变成Rust之前,立即寻找更好的工作。

xsuvu9jc

xsuvu9jc2#

auto是一个类似于static的修饰符。它定义了变量的存储类。但是,由于局部变量的默认值是auto,因此通常不需要手动指定它。
This page列出了C中不同的存储类。

ct2axkht

ct2axkht3#

auto关键字在C语言中是无用的。它在那里是因为在C语言之前存在一种B语言,在这种语言中,该关键字是声明局部变量所必需的。(B发展成NB,NB变成C)。
这里是reference manual for B
如您所见,手册中充斥着使用auto的示例。这是因为没有int关键字。需要某种关键字来表示“这是一个变量的声明”,并且该关键字还指示它是本地还是外部(autoextrn)。如果不使用其中一个,则会出现语法错误。也就是说,x, y;本身不是声明,但auto x, y;是。
由于用B语言编写的代码库必须在语言开发时移植到NB和C,因此该语言的新版本为改进向后兼容性带来了一些负担,这些负担转化为更少的工作。在auto的情况下,程序员不必搜索auto的每个出现并将其删除。
从手册中可以明显看出,现在已经过时的C中的“隐式int”cruft(能够在前面不使用任何int的情况下编写main() { ... })也来自B。这是支持B代码的另一个向后兼容特性。函数没有在B中指定的返回类型,因为没有类型。一切都是一个词,就像许多汇编语言一样。
注意一个函数可以被声明为extrn putchar,然后唯一使它成为标识符的函数的是:它被用在像putchar(x)这样的函数调用表达式中,这就是告诉编译器把这个无类型的字当作函数指针的原因。

v8wbuo2f

v8wbuo2f4#

在C语言中,auto是一个关键字,表示一个变量是块的局部变量。因为这是块作用域变量的默认值,所以它是不必要的,而且很少使用(我想我从来没有见过它在讨论关键字的文本中的示例之外使用)。如果有人能指出需要使用auto来获得正确的解析或行为的情况,我会很感兴趣。
然而,在C++11标准中,auto关键字被“劫持”以支持类型推断,其中变量的类型可以从其初始化器的类型中获取:

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

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

4c8rllxm

4c8rllxm5#

使用旧的阿兹特克C编译器,可以使用命令行开关将所有自动变量转换为静态变量(以提高寻址速度)。
但是在这种情况下,用auto显式声明的变量保持原样。(这是递归函数的必备功能,否则将无法正常工作!)

ubby3x7f

ubby3x7f6#

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');
}

字符串

nwlqm0z1

nwlqm0z17#

auto只能用于块作用域的变量。extern auto int是垃圾,因为编译器无法确定这是否使用了外部定义,或者是否用auto定义覆盖extern(auto和extern是完全不同的存储持续时间,就像static auto int一样,这显然也是垃圾)。它总是可以选择以一种方式解释它,而是选择将其视为错误。
auto确实提供了一个特性,那就是在函数内部启用“一切都是int”规则。在函数外部,a=3被解释为定义int a =3,因为赋值在文件范围内不存在,而在函数内部,a=3是一个错误,因为显然编译器总是将其解释为对外部变量的赋值,而不是定义(即使在函数或文件作用域中没有extern int a前向声明),但可以使用像staticconstvolatileauto意味着它是一个定义,编译器将其作为一个定义,除了auto没有其他说明符的副作用。因此,auto a=3隐含地是auto int a = 3。诚然,signed a = 3具有相同的效果,unsigned a = 3始终是无符号整型。
还要注意' auto对是否将对象分配给寄存器没有影响(除非某些特定的编译器注意到它,但这似乎不太可能)'

iezvtpos

iezvtpos8#

Auto关键字是一个存储类(某种决定变量生存期和存储位置的技术)示例。它有一个行为,通过该行为,由该关键字的Help创建的变量仅驻留在花括号内

{
    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
}

字符串

b0zn9rqh

b0zn9rqh9#

我相信你熟悉C中的存储类说明符,它们是“extern”,“static”,“register”和“auto”。“auto”的定义在其他答案中已经给出了很多,但这里有一个我不确定的“auto”关键字的可能用法,但我认为它依赖于编译器。你看,关于存储类说明符,有一个规则。我们不能为一个变量使用多个存储类说明符。这就是为什么静态全局变量不能被外部化的原因。因此,它们仅对其文件是已知的。当你转到你的编译器设置时,你可以启用优化标志来提高速度。编译器优化的方法之一是,它查找没有存储类说明符的变量,然后基于高速缓存内存的可用性和一些其他因素进行评估,以确定是否应该使用寄存器说明符来处理该变量。现在,如果我们想优化代码的速度,同时知道程序中的某个特定变量不是很重要,我们甚至不希望编译器将其视为寄存器,那该怎么办?我认为通过输入auto,编译器将无法向变量添加寄存器说明符,因为输入“register auto int a;“OR“auto register int a;“引发使用多个存储类说明符的错误。总而言之,我认为auto可以通过优化来禁止编译器将变量视为寄存器。
这个理论不适用于GCC编译器,但我没有尝试过其他编译器。

相关问题