Fortran
Typy danych
Szukaj…
Typy wewnętrzne
Poniżej przedstawiono typy danych właściwe dla Fortran:
integer
real
character
complex
logical
integer
, real
i complex
to typy liczbowe.
character
jest typem używanym do przechowywania ciągów znaków.
logical
służy do przechowywania wartości binarnych .true.
lub .false.
.
Wszystkie numeryczne i logiczne typy wewnętrzne są parametryzowane za pomocą rodzajów.
integer(kind=specific_kind)
Lub tylko
integer(specific_kind)
gdzie specific_kind
jest liczbą całkowitą o nazwie stała.
Zmienne znakowe, oprócz parametru rodzaju, mają również parametr długości:
character char
deklaruje char
jako zmienną char
o długości 1 domyślnego rodzaju, natomiast
character(len=len) name
deklaruje name
jako zmienną znakową o domyślnym rodzaju i długości len
. Rodzaj można również określić
character(len=len, kind=specific_kind) name
character(kind=specific_kind) char
deklaruje name
być charakter rodzaju kind
i długości len
. char
jest długości 1 charakter rodzaju kind
.
Alternatywnie, przestarzała forma deklaracji postaci
character*len name
może być widoczny w starszym kodzie, podając name
o długości len
i domyślny rodzaj znaku.
Deklaracja zmiennej typu wewnętrznego może mieć powyższą formę, ale może również używać formy type(...)
:
integer i
real x
double precision y
jest równoważne (ale znacznie bardziej preferowane)
type(integer) i
type(real) x
type(double precision) y
Pochodne typy danych
Zdefiniuj nowy typ, mytype
typ:
type :: mytype
integer :: int
real :: float
end type mytype
Zadeklaruj zmienną typu mytype :
type(mytype) :: foo
Dostęp do komponentów typu pochodnego można uzyskać za pomocą operatora %
1 :
foo%int = 4
foo%float = 3.142
Funkcja Fortran 2003 (jeszcze nie zaimplementowana we wszystkich kompilatorach) pozwala zdefiniować sparametryzowane typy danych:
type, public :: matrix(rows, cols, k)
integer, len :: rows, cols
integer, kind :: k = kind(0.0)
real(kind = k), dimension(rows, cols) :: values
end type matrix
Pochodna matrix
typów ma trzy parametry typu, które są wymienione w nawiasach po nazwie typu (są to rows
, cols
i k
). W deklaracji każdego parametru typu należy wskazać, czy są to parametry rodzaju ( kind
) czy długość ( len
).
Parametry rodzaju rodzaju, takie jak typy wewnętrzne, muszą być stałymi wyrażeniami, podczas gdy parametry typu długości, takie jak długość wewnętrznej zmiennej znakowej, mogą się zmieniać podczas wykonywania.
Zauważ, że parametr k
ma wartość domyślną, więc można go podać lub pominąć, gdy deklarowana jest zmienna typu matrix
, jak pokazano poniżej
type (matrix (55, 65, kind=double)) :: b, c ! default parameter provided
type (matrix (rows=40, cols=50) :: m ! default parameter omitted
Nazwa typu pochodnego nie może być doubleprecision
lub taka sama jak żaden z typów wewnętrznych.
- Wiele osób zastanawia się, dlaczego Fortran używa
%
jako operatora dostępu do komponentów zamiast bardziej powszechnego.
. To dlatego, że.
jest już zajęty przez składnię operatora, tj.not.
,.and.
,.my_own_operator.
.
Precyzja liczb zmiennoprzecinkowych
Liczby zmiennoprzecinkowe typu real
nie mogą mieć żadnej rzeczywistej wartości. Mogą reprezentować liczby rzeczywiste do pewnej liczby cyfr dziesiętnych.
FORTRAN 77 gwarantował dwa typy zmiennoprzecinkowe, a nowsze standardy gwarantują co najmniej dwa typy rzeczywiste. Rzeczywiste zmienne można zadeklarować jako
real x
double precision y
x
tutaj jest prawdziwym rodzajem domyślnym, a y
jest prawdziwym rodzajem z większą precyzją dziesiętną niż x
. W Fortran 2008 precyzja dziesiętna y
wynosi co najmniej 10, a zakres wykładnika dziesiętnego co najmniej 37.
real, parameter :: single = 1.12345678901234567890
double precision, parameter :: double = 1.12345678901234567890d0
print *, single
print *, double
odciski
1.12345684
1.1234567890123457
we wspólnych kompilatorach korzystających z domyślnej konfiguracji.
Zwróć uwagę na d0
w stałej podwójnej precyzji. Rzeczywisty literał zawierający d
zamiast e
do oznaczenia wykładnika służy do wskazania podwójnej precyzji.
! Default single precision constant
1.23e45
! Double precision constant
1.23d45
Fortran 90 wprowadził sparametryzowane typy real
przy użyciu rodzajów. Rzeczywistym typem jest liczba całkowita o nazwie stała lub stała dosłowna:
real(kind=real_kind) :: x
Lub tylko
real(real_kind) :: x
Ta instrukcja deklaruje, że x
jest typu real
z pewną dokładnością w zależności od wartości typu real_kind
.
Literały zmiennoprzecinkowe można zadeklarować określonym rodzajem przy użyciu sufiksu
1.23456e78_real_kind
Dokładna wartość parametru real_kind
nie jest ustandaryzowana i różni się w zależności od kompilatora. Aby zapytać o prawdziwą zmienną lub stałą, można użyć funkcji kind()
:
print *, kind(1.0), kind(1.d0)
zazwyczaj drukuje
4 8
lub
1 2
w zależności od kompilatora.
Liczby rodzajowe można ustawić na kilka sposobów:
Pojedyncza (domyślna) i podwójna precyzja:
integer, parameter :: single_kind = kind(1.) integer, parameter :: double_kind = kind(1.d0)
Korzystanie z wewnętrznej funkcji
selected_real_kind([p, r])
celu określenia wymaganej dokładności dziesiętnej. Zwracany rodzaj ma dokładność co najmniejp
cyfr i umożliwia wykładnik co najmniejr
.integer, parameter :: single_kind = selected_real_kind( p=6, r=37 ) integer, parameter :: double_kind = selected_real_kind( p=15, r=200 )
Począwszy od Fortran 2003, wstępnie zdefiniowane stałe są dostępne przez wewnętrzny moduł
ISO_C_Binding
aby zapewnić, że typy rzeczywiste są interoperacyjne z typamifloat
,double
lublong_double
towarzyszącego kompilatora C:use ISO_C_Binding integer, parameter :: single_kind = c_float integer, parameter :: double_kind = c_double integer, parameter :: long_kind = c_long_double
Począwszy od Fortran 2008, wstępnie zdefiniowane stałe są dostępne poprzez wewnętrzny moduł
ISO_Fortran_env
. Te stałe zapewniają rzeczywiste rodzaje o określonej wielkości pamięci w bitachuse ISO_Fortran_env integer, parameter :: single_kind = real32 integer, parameter :: double_kind = real64 integer, parameter :: quadruple_kind = real128
Jeśli pewien rodzaj nie jest dostępny w kompilatorze, wartość zwracana przez selected_real_kind()
lub wartość stałej całkowitej wynosi -1
.
Zakładane i odroczone parametry typu długości
Zmienne typu znakowego lub typu pochodnego z parametrem length mogą mieć parametr długości przyjęty lub odroczony . Zmienny charakter name
character(len=len) name
ma długość len
podczas wykonywania. I odwrotnie, specyfikatorem długości może być albo
character(len=*) ... ! Assumed length
lub
character(len=:) ... ! Deferred length
Zakładane zmienne długości przyjmują długość od innej jednostki.
W funkcji
function f(dummy_name)
character(len=*) dummy_name
end function f
argument dummy_name
ma długość rzeczywistego argumentu.
Nazwana stała const_name
w
character(len=*), parameter :: const_name = 'Name from which length is assumed'
ma długość wyrażoną stałym wyrażeniem po prawej stronie.
Parametry typu odroczonej długości mogą się różnić podczas wykonywania. Zmienna o odroczonej długości musi mieć atrybut allocatable
lub pointer
character(len=:), allocatable :: alloc_name
character(len=:), pointer :: ptr_name
Długość takiej zmiennej można ustawić na jeden z poniższych sposobów
allocate(character(len=5) :: alloc_name, ptr_name)
alloc_name = 'Name' ! Using allocation on intrinsic assignment
ptr_name => another_name ! For given target
W przypadku typów pochodnych z parametryzacją długości składnia jest podobna
type t(len)
integer, len :: len
integer i(len)
end type t
type(t(:)), allocatable :: t1
type(t(5)) t2
call sub(t2)
allocate(type(t(5)) :: t1)
contains
subroutine sub(t2)
type(t(*)), intent(out) :: t2
end subroutine sub
end
Stałe dosłowne
Jednostki programowe często używają literalnych stałych. Obejmują one oczywiste przypadki, takie jak
print *, "Hello", 1, 1.0
Z wyjątkiem jednego przypadku, każda stała literalna jest skalarem, który ma typ, parametry typu i wartość podane przez składnię.
Stałe literałowe liczb całkowitych mają postać
1
-1
-1_1 ! For valid kind parameter 1
1_ik ! For the named constant ik being a valid kind paramter
Rzeczywiste stałe literalne mają formę
1.0 ! Default real
1e0 ! Default real using exponent format
1._1 ! Real with kind parameter 1 (if valid)
1.0_sp ! Real with kind paramter named constant sp
1d0 ! Double precision real using exponent format
1e0_dp ! Real with kind named constant dp using exponent format
Złożone stałe literalne mają formę
(1, 1.) ! Complex with integer and real components, literal constants
(real, imag) ! Complex with named constants as components
Jeśli rzeczywiste i urojone składniki są liczbami całkowitymi, złożona stała literalna jest domyślnie złożona, a składniki całkowite są konwertowane na domyślne rzeczywiste. Jeśli jeden ze składników jest prawdziwy, parametrem rodzaju złożonej stałej literalnej jest parametr rzeczywistego (a składnik całkowity jest konwertowany na ten rzeczywisty rodzaj). Jeśli oba składniki są prawdziwe, złożona stała literalna jest prawdziwa z największą precyzją.
Logiczne stałe literalne są
.TRUE. ! Default kind, with true value
.FALSE. ! Default kind, with false value
.TRUE._1 ! Of kind 1 (if valid), with true value
.TRUE._lk ! Of kind named constant lk (if valid), with true value
Wartości literałów znakowych różnią się nieznacznie koncepcyjnie, ponieważ specyfikator rodzaju poprzedza wartość
"Hello" ! Character value of default kind
'Hello' ! Character value of default kind
ck_"Hello" ! Character value of kind ck
"'Bye" ! Default kind character with a '
'''Bye' ! Default kind character with a '
"" ! A zero-length character of default kind
Jak sugerowano powyżej, stałe literału znakowego muszą być oddzielone apostrofami lub cudzysłowami, a znacznik początkowy i końcowy muszą się zgadzać. Dosłowne apostrofy można zawrzeć, umieszczając je w ogranicznikach cudzysłowu lub przez podwojenie. To samo dotyczy znaków cudzysłowu.
Stałe BOZ różnią się od powyższego tym, że określają tylko wartość: nie mają typu ani parametru typu. Stała BOZ jest wzorem bitowym i jest określona jako
B'00000' ! A binary bit pattern
B"01010001" ! A binary bit pattern
O'012517' ! An octal bit pattern
O"1267671" ! An octal bit pattern
Z'0A4F' ! A hexadecimal bit pattern
Z"FFFFFF" ! A hexadecimal bit pattern
Stałe literalne BOZ są ograniczone tam, gdzie mogą się pojawić: jako stałe w instrukcjach data
i wybranych procedurach wewnętrznych.
Dostęp do podciągów znaków
Dla bytu postaci
character(len=5), parameter :: greeting = "Hello"
do podłańcucha można odwoływać się za pomocą składni
greeting(2:4) ! "ell"
Aby uzyskać dostęp do jednej litery, nie wystarczy napisać
greeting(1) ! This isn't the letter "H"
ale
greeting(1:1) ! This is "H"
Dla tablicy znaków
character(len=5), parameter :: greeting(2) = ["Hello", "Yo! "]
mamy dostęp do podciągów jak
greeting(1)(2:4) ! "ell"
ale nie możemy odwoływać się do nieciągłych znaków
greeting(:)(2:4) ! The parent string here is an array
Możemy nawet uzyskać dostęp do podciągów literałów stałych
"Hello"(2:4)
Część zmiennej znakowej można również zdefiniować za pomocą podłańcucha jako zmiennej. Na przykład
integer :: i=1
character :: filename = 'file000.txt'
filename(9:11) = 'dat'
write(filename(5:7), '(I3.3)') i
Dostęp do złożonych komponentów
Złożony byt
complex, parameter :: x = (1., 4.)
ma prawdziwą część 1.
i złożoną część 4.
.. Możemy uzyskać dostęp do tych poszczególnych komponentów jako
real(x) ! The real component
aimag(x) ! The complex component
x%re ! The real component
y%im ! The complex component
Forma x%..
jest nowością w Fortran 2008 i nie jest powszechnie obsługiwana w kompilatorach. Tej formy można jednak użyć do bezpośredniego ustawienia poszczególnych składników zmiennej zespolonej
complex y
y%re = 0.
y%im = 1.
Deklaracja i atrybuty
W tutejszych tematach i przykładach zobaczymy wiele deklaracji zmiennych, funkcji i tak dalej.
Oprócz danych, obiekty danych mogą mieć atrybuty . W tym temacie omówiono deklaracje podobne do
integer, parameter :: single_kind = kind(1.)
co daje obiektowi single_kind
atrybut parameter
(co czyni go nazwaną stałą).
Istnieje wiele innych atrybutów, takich jak
-
target
-
pointer
-
optional
-
save
Atrybuty można określić za pomocą tak zwanych instrukcji specyfikacji atrybutów
integer i ! i is an integer (of default kind)...
pointer i ! ... with the POINTER attribute...
optional i ! ... and the OPTIONAL attribute
Jednak ogólnie uważa się, że lepiej jest unikać używania tych instrukcji specyfikacji atrybutów. Dla jasności atrybuty można określić jako część pojedynczej deklaracji
integer, pointer, optional :: i
Zmniejsza to również pokusę używania niejawnego pisania.
W większości przypadków w tej dokumentacji Fortran preferowane jest oświadczenie dotyczące pojedynczej deklaracji.