C语言变量具有三属性类型作用范围、存储类别。存储类别1、auto类别1.1、auto类别的变量使用完后释放所占用空间。auto类别 临时变量1.2、局部变量默认为auto类别无初始化时初值为随机值。局部变量不是所有变量不给初值并不意味着变量没有值实际上是有的而且是随机值。1.3、使用时间短一般都是auto类别的变量。2、static类别2.1、static类别从定义到程序运行结束均占用存储空间。占用时间比auto长。2.2、全局变量默认为static类别无初始化时初值为0。2.3、static类别变量只进行一次初始化。案例1//09-6--001 #include stdio.h int fun(int x, int y) { static int m 0,i 2;//静态变量static i m 1; m i x y; return m; } main() { int j 4, m 1, k; k fun(j, m); printf(%d, k); k fun(j, m); printf(%d, k); }该案例是一个复合框架由一个子函数fun()和一个主函数main()组成。主函数调用子函数两次。从主函数main开始执行定义了3个局部变量j4,m1,k为随机值。接着开始调用子函数函数出门出门时单向传值将j4与m1传至子函数。因此x4,y1继续执行子函数fun()定义了两个静态变量分别是m0,i2静态变量只做一次初始化所以原代码中我们定义好m和i后那一句带static的话就没有用了。继续往下im1是先算m1,放到i里再进行累加。那么i此时i21i3。继续往下mixy其中i3,x4,y1,所以m8。继续往下return m带着m的值返回所哟就带着8返回了。回到主函数原本调用的位置继续运行kfun(j,m)8这个值给了fun()所以fun()8所以k8继续运行打印k的值输出打印8光标在8后。继续运行再次调用子函数函数出门出门时单向传值再次将j4与m1传至子函数。再次运行一遍子函数但是前面已经用过一次static语句了第二次再用就会跳过static语句注意注意此时m的值就不是static初始化的0了i的值也不是初始化的2了而是沿用上一次留下来的数据m8,i3继续使用。继续往下运行im1是先算m1,放到i里再进行累加。m18,819,此时就把9累加进i里i9312i变成12.继续往下运行mixyi12,x4,y1,所以此时m17。继续往下return m那么就带着17回主函数了。回到主函数kfun(),带回来的值是1717这个值给了fun()所以fun()17所以k17继续运行打印k的值输出打印17光标在17后。分析结束所以最后的输出框输出的应该是817。我们上机看一下最终的效果重点体会static变量第一次调用和第二次调用之间的区别。认真体会“static类别变量只进行一次初始化”在代码中的具体体现。案例2//09-6--002 #include stdio.h int d 1; fun(int p) { static int d 5;//静态变量static d p; printf(%d, d); return (d); } main() { int a 3; printf(%d\n, fun(afun(d))); }代码开头有一个d是全局变量。但是在子函数内也有一个d是static变量只做一次初始化。在主函数内也出现了一个d那么这个d就应该是全局变量d因为子函数内的d的作用范围只在子函数内。因此主函数内的fun(d),其中的d1。开始分析。这是个包括一个子函数和一个主函数的复合框架。子函数在上无需声明。在主函数内调用子函数两次。最后printf。fun()子函数前没有规定类型那fun()返回什么类型应该是默认返回Int类型int类型即非void类型一定要加return。从主函数进入开始执行首先定义了一个a3接下来在printf语句内开始两次调用fun()函数先调用内层的函数fun(d)我们已知d1调用完内层的函数会返回一个值来与前面的a相加继续计算再进行一次调用。好那么开始调用fun(d)函数出门前往fun()单向传值那么p1。继续往下static int d5单次初始化那么d此时被初始化为5d5初始化结束后static语句失效。继续往下dp将p的值累加进d后再赋值给d所以此时d的值被更新为6printf语句输出d的值即输出一个6。继续往下return语句带着d的值d6返回原先调用的地方。回到主函数fun(d),带回来的值是66这个值给了fun()所以fun(d)6带入前面的式子那么变成了fun(a6)。又因为原a3所以fun(9)将会再调用一次fun这次带入的值是9。好那么开始调用fun(9)函数出门前往fun()单向传值那么p9。继续往下static语句已经失效了忽略不看直接运行dp此时将p的值累加进d后再赋值给dp9,d6d的值沿用上一次调用留下来的值所以此时d的值被更新为15。继续往下打印d的值所以打印15。继续往下带着15这个值回到原先调用的主函数的地方。回到主函数那么此时fun(a6)的值已被更新为15。printf语句打印15且换行。分析结束所以最终应该输出61515回车光标在下一行开头。我们上机看一下最终的效果重点体会static变量第一次调用和第二次调用之间的区别。认真体会“static类别变量只进行一次初始化”在代码中的具体体现。3、register类别寄存器类别3.1、register类别变量只能是局部变量才能被说明。3.2、register类别变量一般不能直接使用。4、extern类别4.1、extern类别变量可以加大变量的作用范围外部。案例3//09-6--003 #include stdio.h main() { printf(%d,%d\n, x, y); } int x, y;可以看到本案例希望可以实现输出x和y但是代码实际上是先使用再定义原本c语言中应该先定义后使用所以在编译是就会提醒未声明。但是我们代码末尾有定义呀那么我们就可以通过extern来加大x和y的作用范围。增加语句extern x,y;增加句子之后程序正常运行。4.2、格式说明格式1auto、static、register只能使用格式1定义的同时说明类别存储类型 类型名 变量名eg:auto int x;-----auto可省略static int x;-----YES格式2extern可以用格式1也可以用格式2分别定义说明类型名 变量名存储类型 变量名eg:extern int x;或者 int x;extern x;学习过程有诸多不足之处欢迎来私信与我一同交流学习共同进步