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.


  1. 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:

  1. Pojedyncza (domyślna) i podwójna precyzja:

    integer, parameter :: single_kind = kind(1.)
    integer, parameter :: double_kind = kind(1.d0)
    
  2. 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 najmniej p cyfr i umożliwia wykładnik co najmniej r .

    integer, parameter :: single_kind = selected_real_kind( p=6, r=37 )
    integer, parameter :: double_kind = selected_real_kind( p=15, r=200 )
    
  3. 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 typami float , double lub long_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
    
  4. 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 bitach

    use 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.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow