如何在函式內直接改變全域變數?
不經由函式參數而直接在函式內使用全域變數 (global variable),在絕大部分的情況下都不建議這種方式。但可藉著這個問題來說明全域變數,更進一步的解釋什麼是作用範圍 (scope)。
C 語言的全域變數:
.h
內宣告。extern
先宣告。另外說明:函式的使用也同樣要遵循這規則,在另一檔案使用函式前,要用 extern
先宣告。但如果函式已經在標頭檔案 .h
內宣告,而這程式碼檔案 有 #include
標頭檔案,就不需要另外用 extern
宣告,這也是通常建議的方法。
舉例說明:
#include <stdio.h>
int myGlobal = 10; // 全域變數
void myFunc() {
myGlobal += 3;
printf("在函式內, myGlobal = %d\n", myGlobal);
}
int main() {
printf("執行函式前, myGlobal = %d\n", myGlobal);
myFunc();
printf("執行函式後, myGlobal = %d\n", myGlobal);
return 0;
}
/* 輸出:
執行函式前, myGlobal = 10
在函式內, myGlobal = 13
執行函式後, myGlobal = 13
*/
Python 的全域變數:
在函式以外宣告的變數稱為全域變數 (global variable),它的作用範圍 (scope) 為整個程式碼。在程式的所有位置都可以使用這變數,但不建議在函式內直接使用全域變數。
如果在函式內要改變全域變數的值,要先用 global
宣告這變數。
my_global = 10 # my_global 是 全域變數
for num in range(3): # num 也是 全域變數
print(num, end=' ')
def main():
my_var = 5
my_function()
print("全域變數: ", my_global) # 全域變數: 13
# print(f"區域變數: {my_local}") # NameError. 不可使用my_function()的區域變數
print("在for迴圈內, num =", end=' ')
for num in range(my_var): # Pylint, W0621:redefined-outer-name. (和函式外面的全域變數 num 同名)
print(num, end=' ')
print(f"\n在for迴圈外, num = {num}") # 在for迴圈外, num = 4
def my_function():
my_local = 3
global my_global # 如要改變全域變數的值,就要用 global 宣告
my_global += 3 # 如沒用 global 宣告, 會產生錯誤 UnboundLocalError
print(f"在函式內, my_global = {my_global}") # 在函式內, my_global = 13
print(f"在函式內, num = {num}") # 在函式內, num = 2, (這是全域變數)
# print(f"在函式內, my_var = {my_var}") # NameError. 不可使用main()的區域變數
if __name__ == '__main__':
main()
作用範圍 (scope)
前面我們有談到 全域變數 (global variable) 和 全域範圍 (global scope),接著要更完整介紹整個作用範圍 (scope) 。
作用範圍 (scope) 指的是變數、常數、函式或其他定義語句可以「被存取得到」的範圍。
C 語言的作用範圍
C 語言的區塊 (block) 就是任何以大括號 { .... } 包起來的區域,例如:函式區塊、 if 區塊、for 區塊、while 區塊等
C 語言的區域變數 (local variable) 是指 函式內或 區塊內 宣告的變數,或是參數列的參數。
例如:
for(int i = 0; i < 100; i++) { int num; ... }
區域變數 i
和 num
作用範圍只在區塊內。而在迴圈執行完畢後,就不再有效。
在C語言中,如何在函式執行結束後,仍可以保留區域變數的結果?
只要在區域變數宣告前加上 static
成為靜態變數 (static variable),它只初始化一次,函式執行結束後,靜態變數的值也會被保留,下次再執行函式時,靜態變數將保持上一次的值。
例如:
#include <stdio.h>
void myFunc() {
static int count = 0; // static variable
count += 3;
printf("count = %d\n", count);
}
int main() {
myFunc(); // count = 3
myFunc(); // count = 6
myFunc(); // count = 9
return 0;
}
Python的作用範圍
for i in range(3):
a = i + 3
print(i)
print(f"在for迴圈外, i = {i}") # 在for迴圈外, i = 2
print(f"在for迴圈外, a = {a}") # 在for迴圈外, a = 5
class A_class:
x = 6
def output(self, x): # 這是較好的方式
print(x) # 30, x 是參數
print(self.x) # 6, self.x 是 類別變數
def test(self): # 不建議的方式
print(x) # 13, x 是全域變數, 如沒定義全域變數 x = 13, 則會產生錯誤 NameError
print(self.x) # 6, self.x 是 類別變數
def my_func():
x = 30
a = A_class()
a.output(x) # 將區域變數 x 設為參數
a.test()
x = 13
my_func()