目录
变量详细解释
局部变量
定义变量有三种情况
1在函数的开头定义
2在函数的复合语`句中定义
3在函数的外部定义
前两者所定义的变量都是局部变量,在一个函数的内部定义的变量只在函数范围内有效,也就是说只能在本函数内部引用它们,在复合语句中定义的变量只能在本复合语句内部有效,只能在本复合语句内才能引用它们。
全局变量
在函数外部定义的变量,在整个项目都有效
1全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才会开辟单元
2在同一个源文件中,全局变量和局部变量同名,在局部变量的作用范围内,局部变量有效,全局变量失效。
#include<stdio.h> int a = 3, b = 5; int main() { int a = 4; int b = 3; printf("%d\n", a);//4 printf("%d\n", b);//3 return 0; }
变量的存储方式和生存期
变量值存在的时间就是生存期,变量有两种不同的存储有两种方式,静态存储方式和动态存储方式
供用户使用的存储空间分为三个部分
1程序区
2动态存储区
3静态存储区
全局变量全部放在静态存储区中,在程序开始执行时给全局变量分配存储区,程序执行完毕后释放
在动态存储区存放以下数据
1函数形式参数,在函数调用时给形参分配存储空间
2函数中定义没有用关键字static声明的变量
3函数调用时的现场保护和返回地址等
对应以上这些数据,在函数调用开始时分配动态存储空间,函数结束时释放这些空间,在程序执行时,这些分配和释放是动态的,如果在一个程序中两次调用同一个函数,而在此函数定义了局部变量,在两次调用时分配给这些局部变量的存储空间的地址可能是不相同的
所以每一个变量和函数都有两个属性,数据类型和数据的存储类型
存储类型有4个种类,自动的(auto),静态的(static),寄存器的(register),外部的(extern)
局部变量的存储类型
自动变量
函数的局部变量,如果不专门声明为static(静态)存储类型,都是动态地分配存储空间,数据存储在动态存储区,函数中的形参和在函数中定义的局部变量,包括复合函数中定义的局部变量,在函数调用时分配存储空间,在函数调用结束时自动释放这些存储空间
实际上定义auto变量时,可以将auto省略,int a=3与auto int b=3的效果是一样的
静态局部变量
有时候希望函数的值在函数调用结束后不消失,而能继续保存原值,其占用的内存空间不释放,就可以把这个局部变量变成静态局部变量
#include<stdio.h> //int a = 3, b = 5; int main() { int f(int); int a = 2, i; for ( i = 0; i < 3; i++) { printf("%d\n", f(a)); } //输出 7 8 9 return 0; } int f(int a) { int b = 0;//自动类型的局部变量 static int c = 3;//定义了静态局部变量 b = b + 1;//每次调用f函数的b的值都是0。因为在这个函数的开头都会重新变成0 c = c + 1;//每次调用c的值会随调用的增加而增加 return a + b + c; }
1静态局部变量属于静态存储类别,在静态存储区内分配存储单元,在整个程序运行期间都不释放
2对静态局部变量是在编译是赋初值的,即只赋值初值一次,在程序运行时它已经有初值,以后每次调用函数时,不在重新赋值而只是保留上次函数调用结束时的值 ,而对于自动变量赋初值,不是在编译时进行的,而是在函数调用时进行的,每调用一次函数重新赋一次初值
3如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时会自动赋初值0(整形变量),或者空字符(字符变量),而对自动变量来说,它的值是一个不确定的值,这是因为每次调用结束后存储单元已释放,下次调用时又重新另分配存储单元,而所分配的单元内容是不可知的
4虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用的
寄存器变量(register)
一般情况下,变量(包括静态存储方式和动态存储方式)的值是存放在内存中的,当程序用到哪一个变量的值,由控制器发出指令将内存中该变量的值送到运算器中
如果有一些变量使用频繁,如循环10000次,那每次都要使用某局部变量,从内存存取变量值要花费不少时间,为了提高执行效率,允许将局部变量的值放在CPU的寄存器中,需要时直接从寄存器中取出参加运算,这种变量叫做寄存器变量
全局变量的存储类型
全局变量都是存放在静态存储区中,因此它们的生存期是固定的,存于程序的整个运行过程,一般来说外部变量的定义处开始,到本程序文件的末尾,但是为了扩张外部变量的作用域,出现下面几个情况
1在一个文件内扩展外部变量的作用域
如果外部变量不在文件开头定义,其有效作用范围只限于定义处到文件结束,在定义点之前就不能引用该外部变量,在定义点之前的函数需要引用这个全局变量,则在引用前应该加上extern对该变量作外部变量声明,表示把该外部变量的作用域扩展到此位置
#include<stdio.h> //int a = 3, b = 5; int main() { int max(); extern int a, b, c;//如果没有这个变量声明,会导致出现错误 scanf("%d%d%d", &a, &b, &c); printf("%d\n", max()); return 0; } int a, b, c; int max() { int m; m = a > b ? a : b; if (c > m) m = c; return m; }
将外部变量的作用域扩展到其他文件
一个c程序可以由一个或多个源程序文件组成,怎么让同一个项目下的源文件去使用其他源文件的全局变量
在将外部变量的作用域限制在本文件中
在定义外部变量时,加上static,这样这个外部变量只能在本源文件中,把这种外部变量称为静态外部变量
1不要误认为对外部变量加static声明后才采取静态存储方式,而没有使用static的采取动态存储,声明全局变量和局部变量的存储类型的含义是不同的,对于局部变量来说,声明存储类型的作用是指定变量的存储区域,而对于全局变量来说,由于都是在编译时候分配内存的,都存放在静态存储区,声明存储类型的作用只是变量作用域的扩展问题
变量的作用域和存在性
如果一个变量在文件内或者函数内是有效的,就成该范围是该变量的作用域,如果一个变量值在某一个时刻是存在的,则这个时刻属于该变量的生存期,或称该变量在此时刻存在