存储类别说明符

作者:追风剑情 发布于:2020-1-9 21:45 分类:C

       关键字static和extern的含义取决于上下文。C语言有6个关键字作为存储类别说明符:autoregisterstaticextern_Thread_localtypedef。typedef关键字与任何内存存储无关,把它归于此类有一些语法上的原因。尤其是,在绝大多数情况下,不能在声明中使用多个存储类别说明符,所以这意味着不能使用多个存储类别说明符作为typedef的一部分。唯一例外的是_Thread_local,它可以和static或extern一起使用。

      auto说明符变量是自动存储期,只能用于块作用域的变量声明中。由于在块中声明的变量本身就具有自动存储期,所以使用auto主要是为了明确表达要使用与外部变量同名的局部变量的意图。

      register说明符也只用于块作用域的变量,它把变量归为寄存器类别,请求最快速度访问该变量。同时,还保护了该变量的地址不被获取。

      用static说明符创建的对象具有静态存储期,载入程序时创建对象,当程序结束时对象消失。如果static用于文件作用域声明,作用域受限于该文件。如果static用于块作用域声明,作用域受限于该块。因此,只要程序在运行对象就存在并保留其值,但是只有在执行块内的代码时,才能通过标识符访问。块作用域的静态变量无链接。文件作用域的静态变量具有内部链接。

      extern说明符表明声明的变量定义在别处。如果包含extern的声明具有文件作用域,则引用的变量必须具有外部链接。如果包含extern的声明具有块作用域,则引用的变量可能具有外部链接或内部链接,这链接取决于该变量的定义声明。

小结:存储类别

      自动变量具有块作用域、无链接、自动存储期。它们是局部变量,属于其定义所在块(通常指函数)私有。寄存器变量的属性和自动变量相同,但是编译器会使用更快的内存或寄存器储存它们。不能获取寄存器变量的地址。

      具有静态存储期的变量可以具有外部链接、内部链接或无链接。在同一个文件所有函数的外部声明的变量是外部变量,具有文件作用域、外部链接和静态存储期。如果在这种声明前面加上关键字static,那么其声明的变量具有文件作用域、内部链接和静态存储期。如果在函数中用static声明一个变量,则该变量具有块作用域、无链接、静态存储期。

      具有自动存储期的变量,程序在进入该变量的声明所在块时才为其分配内存,在退出该块时释放之前分配的内存。如果未初始化,自动变量中是垃圾值。程序在编译时为具有静态存储期的变量分配内存,并在程序的运行过程中一直保留这块内存。如果未初始化,这样的变量会被设置为0。

      具有块作用域的变量是局部的,属于包含该声明的块私有。具有文件作用域的变量对文件(或翻译单元)中位于其声明后面的所有函数可见。具有外部链接的文件作用域变量,可用于该程序的其他翻译单元。具有内部链接的文件作用域变量,只能用于其声明所在的文件内。

示例

partb.c文件

  1. #include <stdio.h>
  2.  
  3. // 引用式声明,外部链接
  4. extern int count;
  5. // 静态定义,内部链接
  6. static int total = 0;
  7. // 函数原型
  8. void accumulate(int k); //在此文件中为可选 (即可省略原型声明)
  9.  
  10. void accumulate(int k) // k具有块作用域,无链接
  11. {
  12. // 静态,无链接
  13. static int subtotal = 0;
  14. if (k <= 0)
  15. {
  16. printf("loop cycle: %d\n", count);
  17. printf("subtotal: %d; total: %d\n", subtotal, total);
  18. }
  19. else
  20. {
  21. subtotal += k;
  22. total += k;
  23. }
  24. }

Main.c文件

  1. //Visual Studio中加上这句才可以使用scanf()
  2. //否则只能使用scanf_s()
  3. #define _CRT_SECURE_NO_WARNINGS
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. //malloc()、free()
  8. #include <stdlib.h>
  9. #include <time.h>
  10.  
  11. void report_count();
  12. void accumulate(int k);
  13. int count = 0; // 文件作用域,外部链接
  14.  
  15. //argc: 参数个数 argv[]: 参数数组
  16. //int main(int argc, char **argv)
  17. int main(int argc, char *argv[])
  18. {
  19. int value; // 自动变量
  20. register int i; // 寄存器变量
  21.  
  22. printf("Enter a positive integer (0 to quit): ");
  23. while (scanf("%d", &value) == 1 && value > 0)
  24. {
  25. ++count; //使用文件作用域变量
  26. for (i = value; i >= 0; i--)
  27. accumulate(i);
  28. printf("Enter a positive integer (0 to quit): ");
  29. }
  30. report_count();
  31.  
  32. system("pause");
  33. return 0;
  34. }
  35.  
  36. void report_count()
  37. {
  38. printf("Loop executed %d times\n", count);
  39. }

运行测试

1111.png

标签: C语言

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号