首页 > 代码库 > StdC--06 作用域和可见性
StdC--06 作用域和可见性
HighLight:
1. 变量
2. C程序在内存内分布
3. 修饰变量的关键字
1. 变量
----> 局部变量
生命周期: 从定义到函数结束
作用域: 在定义这个而局部变量的函数内部
----> 静态局部变量
生命周期: 整个程序
作用域: 定义这个而局部变量的函数内部
静态局部变量和局部变量的区别
1 #include <stdio.h> 2 test(){ 3 int j=0; 4 j++; 5 printf("j=%d\n",j); 6 } 7 8 test1(){ 9 static int jj=0; 10 jj++; 11 printf("jj=%d\n",jj); 12 } 13 14 int main() 15 { 16 int i=0; 17 for(i=0;i<5;i++){ 18 test(); 19 } 20 for(i=0;i<5;i++){ 21 test1(); 22 } 23 return 0; 24 }
在对比之下,就可以看出使用static修饰的局部变量的特性,访问范围和普通的局部变量一样,但是在函数执行完毕之后其数值并不会释放。
局部变量加static------>延长作用域 不会因为函数返回而回收
全局变量加static------>限制作用域 在当前源文件中
----> 全局变量
生命周期: 整个程序的声明周期之内
作用域: 整个程序范围
全局变量个局部变量初始化上的区别: 局部变量在没有初始化的情况下是一个随机数据,而没有初始化的全局变量的数值是0。
使用全局变量模拟栈操作:
1 #include <stdio.h> 2 #include <stdbool.h> 3 4 int INDEX; 5 int data[20]; 6 7 bool push(int d){ 8 if(INDEX>=20) 9 return false; 10 data[INDEX++]=d; 11 return true; 12 } 13 14 int pop(){ 15 return data[--INDEX]; 16 } 17 int peak(){ 18 return data[INDEX-1]; 19 } 20 21 bool empty(){ 22 if(INDEX<=0) 23 return true; 24 return false; 25 } 26 27 int main(){ 28 int i=0; 29 for(i=0;i<10;i++) 30 { 31 push(i+1); 32 } 33 34 printf("pop data is %d\n",pop()); 35 printf("pop data is %d\n",pop()); 36 printf("pop data is %d\n",pop()); 37 printf("show the peak %d\n",peak()); 38 printf("pop data is %d\n",pop()); 39 printf("now %s\n",empty()?"empty":"not empty"); 40 return 0;
----> 变量的局部优先原则
局部优先:如果全局变量 局部变量 块变量同名,在块变量访问范围之内,块变量优先,在局部变量访问范围之内,局部变量优先。
1 #include <stdio.h> 2 #include <time.h> 3 4 int main() 5 { 6 int h=0,m=0,s=0; 7 int t=0; 8 while(1) 9 { 10 t = time(0);//get the current time; 11 s=t%60; 12 m=t%3600/60; 13 h=(t%(24*3600)/3600+8)%24; 14 printf("%02d:%02d:%02d\r",h,m,s); //"......\r" 15 fflush(stdout); // fflush 16 while(t==time(0)); 17 } 18 return 0; 19 }
2. C程序在内存内分布
----> (1)代码区(text segment): 存放程序代码的一段区域, 程序段只读, 字面值常量
代码区指令根据程序设计流程依次执行,对于顺序指令,则只会执行一次(每个进程),如果反复,则需要使用跳转指令,如果进行递归,则需要借助栈来实现。
----> (2)全局初始化数据区/静态数据区(Data Segment)。只初始化一次。
----> (3)未初始化数据区(BSS)。在运行时改变其值。
BSS通常存放程序中没有初始化的全局变量和静态变量的一块内存区域
----> (4)堆区(heap)。用于动态内存分配。
申请:malloc remalloc new OC(alloc new init)
释放: free delete OC(release)
使用堆操作的情况:对象太大,事先不知道程序所需要对象的数量和大小
----> (5)栈区(stack)。储存程序中临时创建的局部变量
Stack通常存储: 局部 临时变量,在程序开始时候自动分配内存,结束时候自动释放内存,存储函数的返回指针
3. 修饰变量的关键字
-------------+---------+-------------------
| 作用域 | 可见性
-------------+---------+-------------------
局部变量 | 函数/块 | 函数/块
静态局部变量 | 进程 | 函数/块
全局变量 | 进程 | 所有文件(外部变量)
静态全局变量 | 进程 | 定义文件
-------------+---------+-------------------
全局函数 | 进程 | 所有文件
静态全局函数 | 进程 | 定义文件
-------------+---------+-------------------
--->静态局部变量(static)和全局变量:
(1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
(2)静态局部变量的生存期虽然为整个源程序,只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。
(3)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。
(4)根据静态局部变量的特点, 可以看出它是一种生存期为整个源文件的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。
(5) 全局变量 区别就在于:全局变量在其定义后所有函数都能用,但是静态局部变量只能在一个函数里面用。
---->const: 只读变量,不能被修改
---->register
---->volatile
函数地址---打印函数名