文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言自动变量的类型有哪些及怎么用

2023-06-27 10:46

关注

这篇文章主要介绍“C语言自动变量的类型有哪些及怎么用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C语言自动变量的类型有哪些及怎么用”文章能帮助大家解决问题。

关键字auto

为了更清楚地表达你的意图(例如,为了表明有意覆盖一个外部变量定义,或者强调不要把该变量改为其他存储类别),可以显式使用关键字auto,如下所示:

int main(void){  auto int plox;

关键字auto是存储类别说明符(storage-class specifier)。auto关键字在C++中的用法完全不同,如果编写C/C++兼容的程序,最好不要使用auto作为存储类别说明符。

块作用域无链接意味着只有在变量定义所在的块中才能通过变量名访问该变量(当然,参数用于传递变量的值和地址给另一个函数,但是这是间接的方法)。另一个函数可以使用同名变量,但是该变量是存储在不同内存位置上的另一个变量。

变量具有自动存储期意味着,程序在进入该变量声明所在的块时变量存在,程序在退出该块时变量消失。原来该变量占用的内存位置现在可做他用。

嵌套快的情况

接下来分析一下嵌套块的情况。块中声明的变量仅限于该块及其包含的块使用。

int loop(int n){     int m;          // m in scope     scanf("%d", &m);     {          int i;    // both m and i in scope          for (i = m; i < n; i++)               puts("i is local to a sub-blockn");     }     return m;     // m in scope, i gone}

在上面的代码中,i仅在内层块中可见。如果在内层块的前面或后面使用i,编译器会报错。通常,在设计程序时用不到这个特性。然而,如果这个变量仅供该块使用,那么在块中就近定义该变量也很方便。这样,可以在靠近使用变量的地方记录其含义。另外,这样的变量只有在使用时才占用内存。变量nm分别定义在函数头和外层块中,它们的作用域是整个函数,而且在调用函数到函数结束期间都一直存在。

如果内层块中声明的变量与外层块中的变量同名会怎样?内层块会隐藏外层块的定义。但是离开内层块后,外层块变量的作用域又回到了原来的作用域。程序hiding.c演示了这一过程。

// hiding.c -- variables in blocks#include <stdio.h>int main(){    int x = 30;      // original x    printf("x in outer block: %d at %pn", x, &x);    {        int x = 77;  // new x, hides first x        printf("x in inner block: %d at %pn", x, &x);    }    printf("x in outer block: %d at %pn", x, &x);    while (x++ < 33) // original x    {        int x = 100; // new x, hides first x        x++;        printf("x in while loop: %d at %pn", x, &x);    }    printf("x in outer block: %d at %pn", x, &x);    return 0;}

下面是该程序的输出:

x in outer block: 30 at 0x7fff5fbff8c8x in inner block: 77 at 0x7fff5fbff8c4x in outer block: 30 at 0x7fff5fbff8c8x in while loop: 101 at 0x7fff5fbff8c0x in while loop: 101 at 0x7fff5fbff8c0x in while loop: 101 at 0x7fff5fbff8c0x in outer block: 34 at 0x7fff5fbff8c8

首先,程序创建了变量x并初始化为30,如第1条printf()语句所示。然后,定义了一个新的变量x,并设置为77,如第2条printf()语句所示。根据显示的地址可知,新变量隐藏了原始的x。第3条printf()语句位于第1个内层块后面,显示的是原始的x的值,这说明原始的x既没有消失也不曾改变。也许该程序最难懂的是while循环

while循环的测试条件中使用的是原始的x

while(x++ < 33)

在该循环中,程序创建了第3个x变量,该变量只定义在while循环中。所以,当执行到循环体中的x++时,递增为101的是新的x,然后printf()语句显示了该值。每轮迭代结束,新的x变量就消失。然后循环的测试条件使用并递增原始的x,再次进入循环体,再次创建新的x。在该例中,这个x被创建和销毁了3次。注意,该循环必须在测试条件中递增x,因为如果在循环体中递增x,那么递增的是循环体中创建的x,而非测试条件中使用的原始x

我们使用的编译器在创建while循环体中的x时,并未复用内层块中x占用的内存,但是有些编译器会这样做。

该程序示例的用意不是鼓励读者要编写类似的代码(根据C的命名规则,要想出别的变量名并不难),而是为了解释在内层块中定义变量的具体情况。

没有花括号的块

前面提到一个C99特性:作为循环或if语句的一部分,即使不使用花括号({}),也是一个块。更完整地说,整个循环是它所在块的子块(sub-block),循环体是整个循环块的子块。与此类似,if语句是一个块,与其相关联的子语句是if语句的子块。这些规则会影响到声明的变量和这些变量的作用域。程序forc99.c演示了for循环中该特性的用法。

// forc99.c -- new C99 block rules#include <stdio.h>int main(){    int n = 8;    printf("   Initially, n = %d at %pn", n, &n);    for (int n = 1; n < 3; n++)        printf("      loop 1: n = %d at %pn", n, &n);    printf("After loop 1, n = %d at %pn", n, &n);    for (int n = 1; n < 3; n++)    {        printf(" loop 2 index n = %d at %pn", n, &n);        int n = 6;        printf("      loop 2: n = %d at %pn", n, &n);        n++;    }    printf("After loop 2, n = %d at %pn", n, &n);    return 0;}

假设编译器支持C语言的这个新特性,该程序的输出如下:

Initially, n = 8 at 0x7fff5fbff8c8loop 1: n = 1 at 0x7fff5fbff8c4loop 1: n = 2 at 0x7fff5fbff8c4After loop 1, n = 8 at 0x7fff5fbff8c8loop 2 index n = 1 at 0x7fff5fbff8c0loop 2: n = 6 at 0x7fff5fbff8bcloop 2 index n = 2 at 0x7fff5fbff8c0loop 2: n = 6 at 0x7fff5fbff8bcAfter loop 2, n = 8 at 0x7fff5fbff8c8

需要注意的一点:

支持C99C11有些编译器并不支持C99/C11的这些作用域规则(Microsoft Visual Studio 2012就是其中之一)。有些编译会提供激活这些规则的选项。例如,撰写本书时,gcc默认支持了C99的许多特性,但是要用–std=c99选项激活程序清单12.2中使用的特性:

gcc --std=c99 forc99.c

与此类似,gccclang都要使用–std=c1x-std=c11选项,才支持C11特性

程序forc99.c第1个for循环头中声明的n,其作用域作用至循环末尾,而且隐藏了原始的n。但是,离开循环后,原始的n又起作用了。

第2个for循环头中声明的n作为循环的索引,隐藏了原始的n。然后,在循环体中又声明了一个n,隐藏了索引n。结束一轮迭代后,声明在循环体中的n消失,循环头使用索引n进行测试。当整个循环结束时,原始的n又起作用了。再次提醒读者注意,没必要在程序中使用相同的变量名。如果用了,各变量的情况如上所述。

自动变量的初始化

自动变量不会初始化,除非显式初始化它。考虑下面的声明:

int main(void){  int repid;  int tents = 5;

tents变量被初始化为5,但是repid变量的值是之前占用分配给repid的空间中的任意值(如果有的话),别指望这个值是0。可以用非常量表达式(non-constantexpression)初始化自动变量,前提是所用的变量已在前面定义过:

int main(void){  int repid;  int tents = 5;

关于“C语言自动变量的类型有哪些及怎么用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯