int             a = ;
extern int b;
static int c; int d( int e )
{
int f = ;
register int b;
static int g = ;
extern int a;
...
{
int e;
int a;
extern int h;
...
}
...
{
int x;
int e;
...
}
...
}
static int i()
{
...
}
...

  属于文件作用域的声明在缺省情况下为external链接属性,所以第1行的a的链接属性为external。

  如果b的定义在其他地方,第2行的external关键字在技术上并非必需,但在风格上却是圆环这个关键字为好。

  第3行的static关键字修改了c的缺省链接属性,把它改为为internal。

  声明了变量a和b(具有external链接属性)的其他源文件在使用这两个变量时实际所访问的是声明于此处的两个变量。但是变量c只能由这个源文件访问,因为它具有internal链接属性。

  变量a、b、c的存储类型为静态,表示它们并不是存储于堆栈中。因此,这些变量在程序执行之前创建,并一起保持它们的值,直到程序结束。它程序开始执行时,这是a将初始化为5。

  这些变量的作用域一直延伸到这个源文件结束为止,但第7行和第13行声明的局部变量a和b在那部分程序中将隐藏同名的静态变量。因此,这3个变量的作用域为:

  a 第1到12行, 第17到29行

  b 第2到第6行, 第25到29行

  c 第3到第29行

  第4行声明了2个标识符。d的作用域从第4行直到文件结束。函数d的定义对于这个源文件中任何以后想要调用 它的函数而言直到了函数原型的作用。作为函数名,d在缺省情况下具有external链接属性,所以其他源文件只有在文件上存在d的原型,就可以调用d。如果我们将函数声明为static,就可以把它的链接属性从external为改为internal,但这样做将使其他源文件不能访问这个函数。对于函数而言,存储类型并不是问题,因为代码总是存储于静态内存中。

  参数e不具有链接属性,所以我们只能从函数内部通过名字访问它。它具有自动存储类型,所以它在函数被调用时被创到建,当函数返回时消失。由于局部变量冲突,它的作用域限于第6到11行,第17到19行以及第23到24行。

  第6到8行声明局部变量,所以它们的作用域到函数结束为止。它们不具有链接属性,所以它们不能在函数的外部通过名字访问(这是它们称为局部变量的原因)。f的存储类型是自动,当函数每次被调用时,它通过隐匿赋值被初始化为。b的存储类型是寄存器类型,所以它的初始值是垃圾。g的存储类型是静态,所以它在程序的整个执行过程中一直存在。当程序开始执行时,它被初始化为20。当函数每次被调用时,它并不会被重新初始化。

  第9行的声明并不需要。这个代码块位于第1行声明的作用域之内。

  第12 和 13行为代码块声明局部变量。它们都具有自动存储类型,不具有链接属性,它们的作用域延伸到第16行。这些变量和先前声明的a和e不同,而且由于名字冲突,在这个代码块中,以前声明的同名变量是不能被访问的。

  第14行使全局变量h在这个代码块内可以被访问。它具有external链接属性,存储于静态内存中。这是唯一一个必须使用external关键字的声明,如果没有它,h将变成另一个局部变量。

  第19行和20行用于创建局部变量(自动、无链接属性、作用域限于本代码块)。这个e和参数e是不同的变量,它和第12行声明的e也不相同。在这个代码块中,从第11行到18行并无嵌套,所以编译器可以使用相同的内存来存储两个代码块中不同的变量e。如果你想让这两个代码块的的有表示同一个变量,那么你就不应该把它声明为局部变量。

  最后,第25行声明了函数i,它具有静态链接属性。静态链接属性可以它防止它被这个源文件之外的任何函数调用。事实上,其他的源文件也可能声明它自己的函数i,它与这个源文件的i是不同的函数。i的作用域从它声明的位置直到这个源文件结束。函数d不可以调用函数i,因为d之前不存在i的原型。

  具有external链接属性的实体在其他语言的术语里称为全局实体,所以源文件中的所有函数均可以被访问它。只要变量并非声明于代码块或函数定义内部,它在缺省情况下的链接属性即为external。如果一个变量声明于代码块内部,在它前面添加external关键字将使它所引用的是全局变量而非局部变量。

  具有external链接属性的实体总是具有静态存储类型。全局变量在程序开始执行前创建,并在程序整个执行过程中始终存在。从属于函数的局部变量在函数开始执行时创建,在函数执行完毕后销毁,但用于执行函数的机器指令在程序的生命周期内一直存在。

  局部变量由函数内部使用,不能被其他函数通过名字引用。它在缺省情况下的存储类型为自动,这是基于两个原因:其一,当这些变量需要时才为它们分配存储,这样可以减少内存的总需求量。其二,在堆栈上为它们分配存在可能有效地实现递归。如果你觉得让变量的值在函数的多次调用中始终保持原先的值非常重要的话,你可以修改它的存储类型,把它从自动变量改为静态变量。

作用域、链接属性和存储类型总结
变量类型 声明的位置  是否存于堆栈 作用域 如果声明为static
全局 所有代码块之外 从声明处到文件尾 不允许从其他源文件访问
局部 代码块起始处 整个代码块 变量不存储于堆栈中,它的值在程序整个执行期一起保持
形式参数 函数头部 整个函数 不允许

C和指针 3.9作用域、存储类型示例的更多相关文章

  1. C和指针笔记 3.7 存储类型

    变量的破碎类型是指存储变量值的内存类型.变量的存储类型决定变量何时创建.何时销毁以及它的值将保持多久. 有三个地方可以用于存在变量:普通内存.运行时堆栈.硬件寄存器. 变量的缺省存储类型取决于它的声明 ...

  2. C和C指针小记(六)-基本声明、指针声明、typedef 、常量、作用域、链接属性、存储类型、static

    1.变量的声明 声明变量的基本形式: 说明符号(一个或者多个) 声明表达式列表 说明符 (specifier) 包含一些关键字,用于描述被声明的标识符的基本类型,它也可用户改变标识符的缺省存储类型和作 ...

  3. 关于extern和static关键字引出的一些关于作用域和链接属性和存储类型的问题

    在进入正题前我们必须了解一些概念: 标识符:标识符不仅仅代表着变量的名字,main()函数的main也是一个标识符,这点很重要. 存储类型:即变量的存储位置及其生存周期:静态区:分为两块 .date ...

  4. C语言存储类型及各存储类型作用域和生存域比较

    c语言中的存储类型有`auto`, `extern`, `register`,`static` 这四种,存储类型说明了该变量要在进程的哪一个段中分配内存空间,可以为变量分配内存存储空间的有数据区.BB ...

  5. C语言中标识符的作用域、命名空间、链接属性、生命周期、存储类型

    Technorati 标签: C,标识符,作用域,命名空间,链接属性,生命周期,存储类型,scope,name space,linkage,storage durations,lifetime 无论学 ...

  6. C语言中的作用域,链接属性和存储类型

    作用域 当变量在程序的某个部分被声明的时候,他只有在程序的一定渔区才能被访问,编译器可以确认4种不同类型的作用域:文件作用域,函数作用域,代码块作用域和原型作用域 1.代码块作用域:位于一对花括号之间 ...

  7. C/C++中变量的作用域和存储类型简介

    写在开头 对于很多C/C++的初学者来说,很容易理不清变量的作用域和存储类型这一块的一些概念,也容易将其中的一些概念搞混淆.作为一个C/C++的初学者,笔者希望在这里能够尝试着去理一理这些较为繁杂的概 ...

  8. C语言作用域、链接属性和存储类型

    C/C++中作用域详解 作用域 编译器可以确认的4种作用域-代码块作用域.文件作用域.函数作用域和原型作用域,一般来说,标识符(包括变量名和函数名)声明的位置决定它的作用域. (1)代码块作用域 一对 ...

  9. c 存储类型

    1,c语言中的存储类型(定义变量和函数的可见范围和生命周期)这些说明符放置在它们所修饰的类型之前.下面列出 C 程序中可用的存储类: auto register static extern 2,aut ...

随机推荐

  1. javascript宿主对象之window.screen、window.close()/open()、window.moveTo、window.resizeTo

    window.screen属性所提供的是浏览器以外的信息.这里只简单的概述一下: screen.availWidth - 可用的屏幕宽度 (除去操作系统菜单) screen.availHeight - ...

  2. iScroll-js—“smooth scrolling for the web”

    原文地址: http://bigdots.github.io/2015/12/15/iScroll-js%E2%80%94%E2%80%94smooth%20scrolling%20for%20the ...

  3. How to upgrade workflow assembly in MOSS 2007

    This problem generally start when you are having an existing custom workflow and there are instances ...

  4. UC如被百度控股,手机qq浏览器改如何进攻和防守

    很早以前在公司内部论坛里写的一篇文章,绯闻已经过过去了,现在已物事人物,UC已有阿里大靠山了. ----------------------------------------------- 据网络媒 ...

  5. Android多媒体录制--MediaRecorder视频录制

    Android使用MediaRecorder类进行视频的录制. 需要注意,使用MediaRecorder 录音录像 的设置代码步骤一定要按照API指定的顺序来设置,否则报错 步骤为: 1.设置视频源, ...

  6. 【读书笔记】iOS-写代码注意事项

    一,我是尽早和经常编译的强烈支持者.通常,在写完每个方法或有点难度的代码后,都要尝试进行构建.这是一个好习惯,因为如果在上次成功编译以来添加的代码量很小,那么可以非常容易地缩小编译错误范围.这个方法还 ...

  7. OC--代理模式

    一,代理设计模式的场合: 当对象A发生了一些行为,想告知对象B (让对象B成为对象A的代理对象) 对象B想监听对象A的一些行为 (让对象B成为对象A的代理对象) 当对象A无法处理某些行为的时候,想让对 ...

  8. Web应用程序系统的多用户权限控制设计及实现-登录模块【4】

    通过前三个模块的介绍,把web权限系统开发所需要的基本类,Css文件,EasyUI框架等准备好后,就可以着手开始系统的编码了. 登陆模块是权限处理系统的关键,根据输入用户的的信息,可自动从数据库中加载 ...

  9. iOS支付宝集成时遇到的问题整理(1)

    1.模拟器上运行正常,但是真机调试时报编译链接错误 :ld: '/Users/wangqipeng/Desktop/iOS支付宝官方文档/AlixPayDemo/libcrypto.a(bio_lib ...

  10. 输入三个整数,xyz,最终以从小到大的方式输出。利用中间变量

    <script>function bijiao(){ var x= parseFloat(document.getElementById("X").value); va ...