上一篇我们介绍了副函式的概念,一般来说我们会把特别处理某些资料的部分,另外拉出一个副函式来处理,除了更好阅读之外,也会增加程式的可维护性,当某个功能出问题,只要专注处理负责该功能的函式就可以了。
虽然先前第六篇已经大概介绍过变数的用法跟概念了,不过今天我们来深入介绍变数的使用範围与生命週期吧!
变数的生命週期?
看到生命週期大家或许会有点困惑,变数就是变数还有生命吗?事实上变数会从被宣告的当下诞生,记忆体会分配一个位置给它,直到区块结束、程式结束后就不再有效,会不能存取也找不到它,我们称这个诞生到结束的过程为「变数的生命週期」。
一般介于「{ }」内的变数,变数存在的生命週期会仅限在内,超过「{ }」之外便会消亡,我们可以从以下程式码看见:
#include <stdio.h>int main(){ int i = 10; printf("%d\n",i); for(int i=0; i<5; i++){ printf("%d\n",i); } printf("%d\n",i); return 0;}
第一次宣告的变数是在main function的整数i(为10),而第一次列印的结果也是10。
但第二次宣告的变数在for迴圈中,且为递增的变数i,并随着for迴圈列印了0到4,而不是for迴圈外的10。
但当for迴圈结束后,列印出的变数则是第一次宣告的10。
区域变数、全域变数?
先前我们有提到如果变数被宣告在「{ }」的区域内,那在超过「{ }」的範围后就会消亡,所以我们不可能在变数宣告的区域範围外使用它,而我们称这种变数为「区域变数」;那如果我们要宣告一个全程式区域都可以使用的变数,也就是「全域变数」时要怎么做呢?
区域变数(1) 以函式为範围
但凡离开宣告变数的「{ }」範围外,变数便不可再使用,且主函式宣告的变数,在副函式是不可以使用的,因副函式已经出了主函式範围之外。
#include <stdio.h>void test();int main(){ int x = 10; printf("%d\n",x); test(); printf("%d\n",x); return 0;}void test(){ int x = 5; printf("%d\n",x);}
如同列印结果,主函式宣告的变数出了主函式範围,在副函式是不可使用变数的,但在副函式宣告同名变数并不冲突,只是副函式宣告的变数,也只能在副函式中使用。
(2) 以小区块为範围
前面有提到若离开宣告变数的「{ }」範围外,变数便不可再使用,但若在範围之内的小区块(如for、while、if等等区块)又宣告同名变数,则在小区块内变数将以小区块变数覆盖,但一出小区块範围也不可使用。
#include <stdio.h>int main(){ int i = 10; printf("%d\n",i); for(int i = 1; i<=5; i++){ printf("%d\n",i); } printf("%d\n",i); return 0;}
如同列印结果,在for迴圈区块内又宣告同名变数,在其区块範围内会暂时覆盖,直到离开该区块则区块变数便不可使用。
2. 全域变数
如果要宣告一个全程式都可以使用的「全域变数」,我们将宣告在主函式外,通常为主函式部分之前。
#include <stdio.h>int x = 15;int main(){ printf("%d\n", x); test(); printf("%d\n", x); return 0;}void test(){ printf("%d\n", x);}
可以从结果看到若宣告为全域变数,且未被区域的同名变数覆盖的话,程式的全区域都可以使用这个变数。
小结
变数是有使用的範围的,且出了範围就会自动消亡,而变数诞生至消亡则为变数的生命週期。
非全程式可使用之变数为区域变数,反之则是全域变数。
主函式宣告之变数,出了主函式便不可使用(如到了副函式时);副函式宣告之变数,出了副函式便不可使用(如回到主函式或任何不在副函式範围的地方);被小区块(for、while、if等区块)宣告之变数,出了小区块后便不可使用。
变数是可以被不同範围的同名区域变数覆盖的。