常見塊
在 Fortran 的早期形式中,從子例程和函式可見的唯一建立全域性變數儲存的機制是使用 COMMON
塊機制。這允許變數序列成為名稱並共享共享。
除了命名的公共塊之外,還可能存在空白(未命名)公共塊。
可以宣告一個空白的公共塊
common i, j
而命名塊 variables
可以宣告為
common /variables/ i, j
作為一個完整的例子,我們可以想象一個可以新增和刪除值的例程使用的堆儲存:
PROGRAM STACKING
COMMON /HEAP/ ICOUNT, ISTACK(1023)
ICOUNT = 0
READ *, IVAL
CALL PUSH(IVAL)
CALL POP(IVAL)
END
SUBROUTINE PUSH(IVAL)
COMMON /HEAP/ ICOUNT, ISTACK(1023)
ICOUNT = ICOUNT + 1
ISTACK(ICOUNT) = IVAL
RETURN
END
SUBROUTINE POP(IVAL)
COMMON /HEAP/ ICOUNT, ISTACK(1023)
IVAL = ISTACK(ICOUNT)
ICOUNT = ICOUNT - 1
RETURN
END
通用語句可用於隱式宣告變數的型別並指定 dimension
屬性。僅此行為通常是混淆的充分來源。此外,隱含的儲存關聯和跨程式單元的重複定義的要求使得使用公共塊容易出錯。
最後,公共塊在它們包含的物件中非常受限制。例如,公共塊中的陣列必須具有顯式大小; 可分配的物件可能不會發生; 派生型別不得具有預設初始化。
在現代 Fortran 中,這些變數的共享可以通過使用模組來處理。上面的例子可以寫成:
module heap
implicit none
! In Fortran 2008 all module variables are implicitly saved
integer, save::count = 0
integer, save::stack(1023)
end module heap
program stacking
implicit none
integer val
read *, val
call push(val)
call pop(val)
contains
subroutine push(val)
use heap, only : count, stack
integer val
count = count + 1
stack(count) = val
end subroutine push
subroutine pop(val)
use heap, only : count, stack
integer val
val = stack(count)
count = count - 1
end subroutine pop
end program stacking
命名空白公共塊的行為略有不同。值得注意的是
- 最初可以定義命名公共塊中的物件; 空白常見的物體不得
- 空白公共塊中的物件表現得好像公共塊具有
save
屬性; 當塊不在活動程式單元的範圍內時,沒有save
屬性的命名公共塊中的物件可能變為未定義
後一點可以與現代程式碼中模組變數的行為形成對比。Fortran 2008 中的所有模組變數都是隱式儲存的,當模組超出範圍時不會變為未定義。在 Fortran 2008 模組變數(如命名公共塊中的變數)之前,當模組超出範圍時,它們也將變為未定義。