lecture9一c程序组织 绳伟光 上海交通大学微纳电子学系 2017年03月28日 SHA
lecture 9 —— C程序组织 绳伟光 上海交通大学微纳电子学系 2017年03月28日
内容 存储类别、链接、生存期、作用域 ■C文件结构 ■C程序的文件组织 ■文本排版程序示例 ■c程序的Build 2
存储类别、链接、生存期、作用域 C文件结构 C程序的文件组织 文本排版程序示例 C程序的Build 内容 2
存储类别、链接、生存期、作用域 存储类别:C中的存储类别规定了在内存中存 储数据的方式 作用域:作用域描述了程序中可通过名字访问 标识符的区域 链接:辅助作用域描述标识符的可见性,辅助 链接器进行链接过程 ■生存期:描述了标识符处于有效状态的时间区 间
存储类别:C中的存储类别规定了在内存中存 储数据的方式 作用域:作用域描述了程序中可通过名字访问 标识符的区域 链接:辅助作用域描述标识符的可见性,辅助 链接器进行链接过程 生存期:描述了标识符处于有效状态的时间区 间 存储类别、链接、生存期、作用域 3
作用域 ■c变量的作用域 必块作用域:只在某复合语句规定的块内可见 函数作用域:仅用于goto的标签,表示在某函数体内部有 效,不受块作用域限制 必函数原型作用域:仅在函数原型中可见 void foo(int m,int n,array[m][n]); 文件作用域:处于所有函数外面,从定义处直到当前C文件 结尾可见 ■注:C编译器每次只能编译一个C文件(翻译单元),因 此C编译器的视野范围只有一个C文件大小;链接器视 野范围为所有涉及的目标文件 ■作用域的概念需要从编译器的角度进行理解
C变量的作用域 块作用域:只在某复合语句规定的块内可见 函数作用域:仅用于goto的标签,表示在某函数体内部有 效,不受块作用域限制 函数原型作用域:仅在函数原型中可见 void foo(int m, int n, array[m][n]); 文件作用域:处于所有函数外面,从定义处直到当前C文件 结尾可见 注:C编译器每次只能编译一个C文件(翻译单元),因 此C编译器的视野范围只有一个C文件大小;链接器视 野范围为所有涉及的目标文件 作用域的概念需要从编译器的角度进行理解 作用域 4
关于块的进一步解释 块中声明的变量:当程序进入块中时,变量被 声明并获得空间,离开块时变量被销毁 ■ 块中声明的变量具有块作用域,不能从块外进 行访问 函数体本身就可以看作一个块 ■利用块声明变量的优点: C89规定函数内的变量只能在函数体头部声明,即 使仅仅是临时使用的变量,利用块侧可以打破限制 必减少命名冲突 ■( 99允许变量在块内任何地方声明
关于块的进一步解释 块中声明的变量:当程序进入块中时,变量被 声明并获得空间,离开块时变量被销毁 块中声明的变量具有块作用域,不能从块外进 行访问 函数体本身就可以看作一个块 利用块声明变量的优点: C89规定函数内的变量只能在函数体头部声明,即 使仅仅是临时使用的变量,利用块则可以打破限制 减少命名冲突 C99允许变量在块内任何地方声明 5
不同作用域的相互影响 ■在C程序中,可能相同的标识符表示不同的意思 为了防止语义上的混淆,C借助作用域来区分标识符的具 体含义 最重要的作用域规则:如果在块内声明了一个变量,而 在块外已经有与刚声明的变量同名的变量,则块内的变 量会隐藏(hides)块外的变量,从而不会发生冲突 当离开了块以后,相同的标识符恢复其本来的意义,代 表块外面的变量 6
不同作用域的相互影响 在C程序中,可能相同的标识符表示不同的意思 为了防止语义上的混淆,C借助作用域来区分标识符的具 体含义 最重要的作用域规则:如果在块内声明了一个变量,而 在块外已经有与刚声明的变量同名的变量,则块内的变 量会隐藏(hides)块外的变量,从而不会发生冲突 当离开了块以后,相同的标识符恢复其本来的意义,代 表块外面的变量 6
作用域与变量的隐藏 int(i) /Declaration 1 * Declaration1,i具有静态生 void i f(int①) /Declaration 2 * 存期和文件作用域 1=1; ■ Declaration1,i是函数形参 ,具有块作用域 void g(void) Declaration3,i是自动变量 int①-2; /Declaration 3 具有块作用域 if (i >0){ ■ Declaration4,i同样是一个 int (i); /Declaration 4 * 自动变量,具有更小的块 1=3; 作用域 1=4; C的作用域规则使得可以 区分的正确含义 void h(void) i= 5;
作用域与变量的隐藏 Declaration 1, i具有静态生 存期和文件作用域 Declaration 1, i是函数形参 ,具有块作用域 Declaration 3, i是自动变量 ,具有块作用域 Declaration 4, i同样是一个 自动变量,具有更小的块 作用域 C的作用域规则使得可以 区分i的正确含义 7
链接((linkage) C变量具有三种链接属性:外部链接、内部链接、无 链接 ~具有块作用域、函数作用域和函数原型作用域的变量都是 无链接的变量 ~外部链接或内部链接特指文件作用域的变量,内部链接变 量只能在一个翻译单元中使用 文件作用域变量默认具有外部链接,加static修饰后具有内 部链接 int aaa;// external linkage static int bbb;/internal linkage int main(){ 8
C变量具有三种链接属性:外部链接、内部链接、无 链接 具有块作用域、函数作用域和函数原型作用域的变量都是 无链接的变量 外部链接或内部链接特指文件作用域的变量,内部链接变 量只能在一个翻译单元中使用 文件作用域变量默认具有外部链接,加static修饰后具有内 部链接 链接(linkage) 8 int aaa;// external linkage static int bbb; // internal linkage int main() { ... }
生存期 ■C对象有四种生存期:自动存储生存期、静态生存期 、动态分配生存期、线程存储生存期 ?自动存储生存期:变量的生存期由编译器自动管理,一般 随着进入块分配内存,块结束时释放内存 ·静态生存期:在程序执行期间一直有效 动态分配生存期:指在堆中分配的变量,随着malloc生效, 生存期持续至调用free函数 线程存储生存期:本课程不涉及 注:对于文件作用域的变量,static关键字只是规定 是否具有内部链接,所有文件作用域变量都具有静态 生存期;对于块作用域变量,可以声明时加static关 键字表示具有静态生存期
C对象有四种生存期:自动存储生存期、静态生存期 、动态分配生存期、线程存储生存期 自动存储生存期:变量的生存期由编译器自动管理,一般 随着进入块分配内存,块结束时释放内存 静态生存期:在程序执行期间一直有效 动态分配生存期:指在堆中分配的变量,随着malloc生效, 生存期持续至调用free函数 线程存储生存期:本课程不涉及 注:对于文件作用域的变量,static关键字只是规定 是否具有内部链接,所有文件作用域变量都具有静态 生存期;对于块作用域变量,可以声明时加static关 键字表示具有静态生存期 生存期 9
存储类别 表:本课程涉及的存储类别 存储类别 生存 作用 链 声明方式 期 接 自动 自动 块 无 块内用auto修饰,默认省略 寄存器 自动 块 无 块内,使用register修饰 静态外部链接 静态 文件 外部 所有函数外 静态内部链接 静态 文件 内部 所有函数外,用static修饰 静态无链接 静态 块 无 块内,用static修饰 动态分配 动态 N/A N/A malloc() 动态分配变量放在后续课中,与内存管理一起讲解! 10
存储类别 生存 期 作用 域 链 接 声明方式 自动 自动 块 无 块内用auto修饰,默认省略 寄存器 自动 块 无 块内,使用register修饰 静态外部链接 静态 文件 外部 所有函数外 静态内部链接 静态 文件 内部 所有函数外,用static修饰 静态无链接 静态 块 无 块内,用static修饰 动态分配 动态 N/A N/A malloc() 存储类别 10 动态分配变量放在后续课中,与内存管理一起讲解! 表:本课程涉及的存储类别