Zoeken…


Intrinsieke typen

De volgende soorten gegevens zijn inherent aan Fortran:

integer
real
character
complex
logical

integer , real en complex zijn numerieke typen.

character is een type dat wordt gebruikt om tekenreeksen op te slaan.

logical wordt gebruikt om binaire waarden .true. te slaan .true. of .false. .

Alle numerieke en logische intrinsieke typen worden met behulp van soorten geparametriseerd.

integer(kind=specific_kind)

of gewoon

integer(specific_kind)

waarbij specific_kind een geheel getal met de naam constante is.

Tekenvariabelen hebben naast een soortparameter ook een lengte-parameter:

character char

verklaart char als een lengte-1 karaktervariabele van het standaardtype, terwijl

character(len=len) name

verklaart name als een karaktervariabele van standaardsoort en lengte len . Het soort kan ook worden opgegeven

character(len=len, kind=specific_kind) name
character(kind=specific_kind) char

verklaart name om een teken van aard zijn kind en de lengte len . char een lengte 1 karakter aard kind .

Als alternatief is het verouderde formulier voor tekendeclaratie

character*len  name

kan gezien worden bij oudere code, waarbij name van de lengte tot zijn len en de standaard karakter soort.


Aangifte van een variabele van het intrinsieke type kan van het bovenstaande formulier zijn, maar kan ook het type(...) formulier gebruiken:

integer i
real x
double precision y

is gelijk aan (maar heeft de voorkeur boven)

type(integer) i
type(real) x
type(double precision) y

Afgeleide gegevenstypen

Definieer een nieuw type, mytype :

type :: mytype
  integer :: int
  real    :: float
end type mytype

Verklaar een variabele van type mijntype :

type(mytype) :: foo

De componenten van een afgeleid type zijn toegankelijk met de operator % 1 :

foo%int = 4
foo%float = 3.142

Met een Fortran 2003-functie (nog niet door alle compilers geïmplementeerd) kunnen geparametriseerde gegevenstypen worden gedefinieerd:

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

De afgeleide matrix heeft drie typeparameters die tussen haakjes worden vermeld na de typenaam (dit zijn rows , cols en k ). In de verklaring van elke typeparameter moet worden aangegeven of het om parameters van het type type ( kind ) of lengte ( len ) gaat.

Soort typeparameters, zoals die van de intrinsieke typen, moeten constante uitdrukkingen zijn, terwijl lengtetypeparameters, zoals de lengte van een intrinsieke karaktervariabele, tijdens uitvoering kunnen variëren.

Merk op dat parameter k een standaardwaarde heeft, dus deze kan als volgt worden opgegeven of weggelaten wanneer een variabele van de matrix wordt gedeclareerd

type (matrix (55, 65, kind=double)) :: b, c ! default parameter provided
type (matrix (rows=40, cols=50)     :: m    ! default parameter omitted

De naam van een afgeleid type is mogelijk geen doubleprecision of hetzelfde als een van de intrinsieke typen.


  1. Veel mensen vragen zich af waarom Fortran % gebruikt als de operator voor componenttoegang in plaats van de meer gebruikelijke . . Dit komt omdat . wordt al gebruikt door de syntaxis van de operator, dat wil zeggen .not. , .and. , .my_own_operator. .

Precisie van drijvende kommagetallen

Drijvende-kommagetallen van het type real kunnen geen echte waarde hebben. Ze kunnen reële getallen vertegenwoordigen tot een bepaald aantal decimale cijfers.

FORTRAN 77 garandeerde twee drijvende komma types en meer recente normen garanderen minstens twee echte types. Echte variabelen kunnen worden opgegeven als

real x
double precision y

x hier een echte standaardwaarde en y is een echte standaard met grotere decimale precisie dan x . In Fortran 2008 is de decimale precisie van y ten minste 10 en het decimale exponentbereik ten minste 37.

 real, parameter             :: single = 1.12345678901234567890
 double precision, parameter :: double = 1.12345678901234567890d0
 
 print *, single
 print *, double

prints

   1.12345684    
   1.1234567890123457

in algemene compilers die standaardconfiguratie gebruiken.

Let op de d0 in de dubbele precisieconstante. Een echte letter die d plaats van e voor het aanduiden van de exponent wordt gebruikt om dubbele precisie aan te geven.

! Default single precision constant
1.23e45
! Double precision constant
1.23d45

Fortran 90 introduceerde geparametriseerde real types met behulp van soorten. Het soort echte type is een geheel getal met de naam constante of letterlijke constante:

real(kind=real_kind) :: x

of gewoon

real(real_kind) :: x

Deze verklaring verklaart x van het type real met een bepaalde precisie, afhankelijk van de waarde van real_kind .

Drijvende-komma-letterlijke waarden kunnen met een specifiek soort worden verklaard met behulp van een achtervoegsel

1.23456e78_real_kind

De exacte waarde van real_kind is niet gestandaardiseerd en verschilt van compiler tot compiler. Om het soort echte variabele of constante te onderzoeken, kan de functie kind() worden gebruikt:

print *, kind(1.0), kind(1.d0)

wordt meestal afgedrukt

4 8

of

1 2

afhankelijk van de compiler.

Soort nummers kunnen op verschillende manieren worden ingesteld:

  1. Enkele (standaard) en dubbele precisie:

    integer, parameter :: single_kind = kind(1.)
    integer, parameter :: double_kind = kind(1.d0)
    
  2. De intrinsieke functie selected_real_kind([p, r]) om de vereiste decimale precisie te specificeren. De geretourneerde soort heeft een precisie van minimaal p cijfers en staat een exponent van minimaal r .

    integer, parameter :: single_kind = selected_real_kind( p=6, r=37 )
    integer, parameter :: double_kind = selected_real_kind( p=15, r=200 )
    
  3. Vanaf Fortran 2003 zijn vooraf gedefinieerde constanten beschikbaar via de intrinsieke module ISO_C_Binding om ervoor te zorgen dat echte soorten interoperabel zijn met de typen float , double of long_double van de bijbehorende C-compiler:

    use ISO_C_Binding
    
    integer, parameter :: single_kind = c_float
    integer, parameter :: double_kind = c_double
    integer, parameter :: long_kind = c_long_double
    
  4. Vanaf Fortran 2008 zijn vooraf gedefinieerde constanten beschikbaar via de intrinsieke module ISO_Fortran_env . Deze constanten bieden echte soorten met een bepaalde opslaggrootte in bits

    use ISO_Fortran_env
    
    integer, parameter :: single_kind = real32
    integer, parameter :: double_kind = real64
    integer, parameter :: quadruple_kind = real128
    

Als een bepaald type niet beschikbaar is in de compiler, is de waarde die door selected_real_kind() geretourneerd of de waarde van de constante integer gelijk aan -1 .

Aangenomen en uitgestelde lengtetypeparameters

Variabelen van het karaktertype of van een afgeleid type met lengte-parameter kunnen de lengte-parameter verondersteld of uitgesteld hebben . De name tekenvariabele

character(len=len) name

is van lengte len tijdens uitvoering. Omgekeerd kan de lengte-specificator beide zijn

character(len=*) ...  ! Assumed length

of

character(len=:) ...  ! Deferred length

Aangenomen dat lengtevariabelen hun lengte aannemen van een andere entiteit.

In de functie

function f(dummy_name)
  character(len=*) dummy_name
end function f

het dummy-argument dummy_name heeft de lengte van het feitelijke argument.

De benoemde constante const_name in

character(len=*), parameter :: const_name = 'Name from which length is assumed'

heeft lengte gegeven door de constante uitdrukking aan de rechterkant.


Parameters van het uitgestelde lengtetype kunnen tijdens de uitvoering variëren. Een variabele met uitgestelde lengte moet het allocatable of het kenmerk pointer hebben

character(len=:), allocatable :: alloc_name
character(len=:), pointer :: ptr_name

De lengte van een dergelijke variabele kan op een van de volgende manieren worden ingesteld

allocate(character(len=5) :: alloc_name, ptr_name)
alloc_name = 'Name'         ! Using allocation on intrinsic assignment
ptr_name => another_name    ! For given target

Voor afgeleide typen met lengteparameterisatie is de syntaxis vergelijkbaar

  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  

Letterlijke constanten

Programma-eenheden maken vaak gebruik van letterlijke constanten. Deze dekken de voor de hand liggende gevallen zoals

print *, "Hello", 1, 1.0

Behalve in één geval is elke letterlijke constante een scalair met type, typeparameters en waarde die door de syntaxis worden gegeven.

Integere letterlijke constanten zijn van de vorm

1
-1
-1_1   ! For valid kind parameter 1
1_ik   ! For the named constant ik being a valid kind paramter

Echte letterlijke constanten zijn van de vorm

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

Complexe letterlijke constanten zijn van de vorm

(1, 1.)       ! Complex with integer and real components, literal constants
(real, imag)  ! Complex with named constants as components

Als de reële en imaginaire componenten beide een geheel getal zijn, is de complexe letterlijke constante standaardcomplex en worden de gehele componenten omgezet in standaardreal. Als een component echt is, is de soortparameter van de complexe letterlijke constante die van de reële (en de component integer wordt geconverteerd naar die echte soort). Als beide componenten echt zijn, is de complexe letterlijke constante van de soort met de grootste precisie.

Logische letterlijke constanten zijn

.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

Letterlijke tekenwaarden verschillen enigszins in concept, in die zin dat de soortspecificatie de waarde voorafgaat

"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

Zoals hierboven gesuggereerd, moeten letterlijke tekenconstanten worden gescheiden door apostrofs of aanhalingstekens en moeten de begin- en eindmarkering overeenkomen. Letterlijke apostrofs kunnen worden opgenomen door tussen aanhalingstekens te staan of door dubbel te verschijnen. Hetzelfde voor aanhalingstekens.

BOZ-constanten onderscheiden zich van het bovenstaande, omdat ze alleen een waarde opgeven: ze hebben geen type of type parameter. Een BOZ-constante is een bitpatroon en wordt opgegeven als

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

BOZ-letterlijke constanten zijn beperkt waar ze kunnen verschijnen: als constanten in data en een selectie van intrinsieke procedures.

Toegang krijgen tot tekensubstrings

Voor de karakterentiteit

character(len=5), parameter :: greeting = "Hello"

naar een substring kan worden verwezen met de syntaxis

greeting(2:4)  ! "ell"

Om toegang te krijgen tot een enkele letter is het niet voldoende om te schrijven

greeting(1)    ! This isn't the letter "H"

maar

greeting(1:1)  ! This is "H"

Voor een character array

character(len=5), parameter :: greeting(2) = ["Hello", "Yo!  "]

we hebben substring toegang zoals

greeting(1)(2:4)  ! "ell"

maar we kunnen niet verwijzen naar de niet-aaneengesloten tekens

greeting(:)(2:4)  ! The parent string here is an array

We hebben zelfs toegang tot substrings van letterlijke constanten

"Hello"(2:4)

Een gedeelte van een tekenvariabele kan ook worden gedefinieerd door een substring als variabele te gebruiken. Bijvoorbeeld

integer :: i=1
character :: filename = 'file000.txt'

filename(9:11) = 'dat'
write(filename(5:7), '(I3.3)') i

Toegang tot complexe componenten

De complexe entiteit

complex, parameter :: x = (1., 4.)

heeft echt deel 1. en complex deel 4. .. We hebben toegang tot deze afzonderlijke componenten als

real(x)  ! The real component
aimag(x) ! The complex component
x%re     ! The real component
y%im     ! The complex component

De x%.. -vorm is nieuw in Fortran 2008 en wordt niet breed ondersteund in compilers. Deze vorm kan echter worden gebruikt om de afzonderlijke componenten van een complexe variabele direct in te stellen

complex y
y%re = 0.
y%im = 1.

Verklaring en attributen

In de onderwerpen en voorbeelden hier zien we veel verklaringen van variabelen, functies, enzovoort.

Naast hun naam kunnen gegevensobjecten attributen hebben . In dit onderwerp worden verklaringen zoals verklaringen behandeld

integer, parameter :: single_kind = kind(1.)

die het object single_kind het parameter geeft (waardoor het een benoemde constante wordt).

Er zijn veel andere attributen, zoals

  • target
  • pointer
  • optional
  • save

Attributen kunnen worden gespecificeerd met zogenaamde kenmerkspecificaties

integer i    ! i is an integer (of default kind)...
pointer i    ! ... with the POINTER attribute...
optional i   ! ... and the OPTIONAL attribute

Over het algemeen wordt het als beter beschouwd om te voorkomen dat deze kenmerkspecificaties worden gebruikt. Voor de duidelijkheid kunnen de attributen worden gespecificeerd als onderdeel van een enkele verklaring

integer, pointer, optional :: i

Dit vermindert ook de verleiding om impliciet typen te gebruiken.

In de meeste gevallen heeft deze Fortran-documentatie de voorkeur aan deze enkele verklaring.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow