C语言作用域、生长周期、链接属性

1、作用域详解

1.1、局部变量的代码块作用域
(1)代码块基本可以理解为一对大括号{}括起来的部分。
(1)代码块不等于函数,因为if while for都有{}。所以代码块<=函数
(3)局部变量的作用域是代码块作用域,也就是说一个局部变量可以被访问和使用的范围仅限于定义这个局部变量的代码块中定义式之后的部分。
2、函数名和全局变量的文件作用域
(1)文件作用域的意思就是全局的访问权限,也就是说整个.c文件中都可以访问这些东西。这就是平时所说的局部和全局,全局就是文件作用域。
(2)详细准确地说就是,函数和全局变量的作用域是定义所在的整个.c文件之内定义之后的部分。
总结:
(1)局部变量、全局变量、函数,都需要先定义才能使用。
(2)准确来说,全局变量函数的作用域都是自己所在的代码块/文件,但是定义式之前的部分因为缺少声明所以没法用。解决方案是:1、把它定义到前面去;2、定义在后面到那时在前面加声明;局部变量因为没法声明,只能定义到前面去。
3、同名变量的掩盖原则
(1)问题:编程时,不可避免会出现同名变量,变量同名后不一定出错。
(2)首先,如果两个同名变量作用域不同且没有交叉,这种情况下同名没有任何影响
(3)其次,如果两个同名变量作用域有交叉,C语言规定在作用域交叉范围内,作用域小的一个变量会掩盖掉作用域大的那个。

2、变量的生长周期

1、栈变量的生命周期
(1)局部变量(栈变量)存储在栈上,生命周期是临时的,临时的意思是说代码执行过程中按照需要去创建、使用、消亡的
(2)譬如一个函数内定义的局部变量,在这个函数每一次被调用的时候都会创建一次,然后使用,最后在函数返回的时候消亡。
(3)函数内的局部变量不能再函数外使用,局部变量分配在栈上。
2、堆变量的生长周期
(1)堆内存是客观存在的,是由操作系统决定的,只是我们需要使用的时候去申请就行
(2)堆内存的生长周期:从malloc申请开始,然后使用,到free结束。
(3)所以堆内存在malloc之前和free之后不能再去访问,因此堆内存在实践中都是被反复的malloc和free的。
3、数据段、bss段变量的生长周期
(1)全局变量的生长周期是永久的,也就是说在程序执行时产生,程序结束后停止。
(2)全局变量所占用的内存是不能被程序自己释放的,所以程序如果申请了过多的全局变量会导致这个程序一直占用大量内存。
4、代码段、只读段的生长周期
(1)其实就是程序执行的代码,也就是函数,生长周期是永久的。

3、链接属性

1、C语言程序额度组织架构
(1)C语言程序由多个c文件和h文件
(2)程序生成的过程:编译+链接。编译就是将函数/变量编程.o二进制额机器码格式,链接是为了将各个独立分开的二进制的函数链接起来就形成了一个整体的二进制可执行程序
2、编译以文件为单位、链接以工程为单位
(1)编译器工作时是将所有源文件依次读进来,单个文件单位进行编译的
(2)链接的时候实际上是把第一步编译生成的单个的.o文件整体的输入,然后处理链接成一个可执行程序。
3、链接属性:外链接、内链接、无链接
(1)外链接的意思就是外部链接属性,在整个程序范围内链接(可以跨文件),譬如函数和全局变量属于外链接。普通的函数/全局变量属于外链接
(2)内链接的意思就是C文件内部的链接属性,可以在当前c文件内部范围内进行链接。static修饰的函数/全局变量属于内链接
(3)无链接的意思就是这个符号本身不参与链接,她与链接没关系。局部变量(auto、static)都是无链接的
4、函数和全局变量的同名冲突
(1)因为函数和全局变量是外部链接属性,就是说每一个函数和全局变量在整个程序中所有的c文件都能被访问,因此在一个程序中的所以c文件中不能出现同名的函数/全局变量。
(2)解决方法就是起名字不要重复,但是很难做到。另外一种方法就是命名空间namespace(其实就是给一个变量带上各个级别的前缀),但是c语言不是这样做的。
(3)c语言解决的方法是:将明显不会在其他c文件中引用(只在当前c文件中引用)的函数/全局变量,使用static修饰使其成为内链接属性,这样在将来链接时即使2个c文件中有重名的函数/全局变量,只要其中一个或2个为内链接属性就没事
5、static的第二种作用:修饰全局变量和函数
(1)普通的(非静态)的函数/全局变量,默认的链接属性是外部的
(2)static(静态)的函数/全局变量,链接属性是内部链接
总结:
(1)普通(自动)局部变量分配在栈上,作用域为代码块作用域,生命周期是临时的,链接属性为无链接。定义时如果未显示初始化则其值随机,变量地址由运行时在栈上分配得到,多次执行时地址不一定想吐,函数不能返回该类变量的地址(指针)作为返回值。
(2)静态局部变量分配在数据段/bss段(显示初始化为非0,则在数据段;显示初始化为0或为现实,则在bss段),作用域为代码块作用域,生命周期是永久的,链接属性为无链接。定义时如果未显示初始化则其值为0,变量地址由运行环境在加载程序时确定,整个程序运行过程中唯一不变;静态局部变量其实就是作用域为代码块作用域(同时链接属性为无链接)的全局变量。静态局部变量可以改为全局变量实现(程序中尽量避免用全局变量,因为会破坏结构性)。
(3)静态局部变量/景泰函数和普通全局变量/普通函数唯一的差别是:static使全局变量/函数的链接属性由外部链接(整个程序所有文件范围)转化为内部链接(当前c文件内)
(4)写程序时尽量避免使用全局变量,尤其是非static类型的全局变量
(5)全局变量应该定义在c文件中并且在头文件中声明
(6)存储类决定生命周期,作用域决定链接属性
(7)宏和inline函数的链接属性为无链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值