You are on page 1of 7

# Complex Data Type

This intrinsic data type has the same precision as default REAL and has comparable properties to other intrinsic data types. A COMPLEX object is made up from two default REAL cells and is declared as follows:
COMPLEX :: z, j, za(1:100)

Symbolic constants are expressed as a co-ordinate pair:
COMPLEX, PARAMETER :: i = (0.0,1.0)

Real-valued literals and symbolic constants, and complex valued literals and symbolic constants can all be used in a COMPLEX object initialisation statement (for example, PARAMETER statement), but it is not permissible to allow a constructed value containing real-valued symbolic constants as components. So,
INTEGER, COMPLEX, COMPLEX, COMPLEX, PARAMETER PARAMETER PARAMETER PARAMETER :: :: :: :: a1 = 1, a2 = 2 i = (1.0,2.0) ii = i iii = a1

is OK, but is
COMPLEX, PARAMETER :: iv = (a1,a2) no good. The CMPLX constructor cannot be used

in initialisation expressions.

Complex values can be constructed elsewhere using the CMPLX intrinsic function,
z = CMPLX(x,y)

This format must be used if the RHS is not a literal constant. It is recommended that the CMPLX intrinsic be used even when the RHS is a literal value (except in PARAMETER statements) as this makes the program more consistent and highlights the type conversion,
z = CMPLX(3,6.9)

Type coercion behaves exactly as for the REAL data type, for example, if a COMPLEX literal contained integers, (1,1), these would be promoted to REAL values before assignment to the COMPLEX variable. Complex expressions can be used in the same way as other types
REAL :: x; COMPLEX :: a, b, c, ... a = x*((b+c)*CMPLX(0.1,-0.1)) b = 1

The real value x will be promoted to the complex value CMPLX(x,0). b will be set to CMPLX(1.0,0). If necessary all other data types are promoted to complex values. When a noncomplex value is coerced a 0.0 is placed in the complex part of the coordinate pair.

If "ivar" is an integer variable then the statement pvar = &ivar results in "pvar" containing an integer giving the address in memory of "ivar". The pointer variable provides more than expanded power in C functions. which can be set to contain the actual memory address of a normal C variable. a case(b) print*.Switch/Case selectcase(var) case(a) print*. What we got was something a little different. and the ability to use and change the contents of that memory location (ivar). and cannot change its value. The C declaration: int *pvar Sets the variable "pvar" as a pointer to integer type variables. the Fortran 90 POINTER does point to variables of your choice. If variable "ivar" is an argument to a C function.. that says we are dealing with a pointer variable. When the Fortran 90 standard was being established. and subsequent locations if "ivar" is an array. The C function can only use its value as passed through a separate memory location. One underlying theme of new Fortran 90 constructs has been isolation of users from the details of memory allocation. b end select POINTERS Pointers have always been a key feature in the C programming language. One reason is the way C passes arguments to functions. I can then pass "pvar" as an argument to the function. As you may recall Fortran passes a function the address of an argument. giving it knowledge of the actual location of "ivar" (just as a Fortran function would have). and in some respects intentionally crippled. there was a request for this feature. this is not a bad thing. the function itself has no idea where the original variable is located. C simply passes the value of the argument to the function. It's the "*" before "pvar". so that both function and calling routine agree on the location of the corresponding variable in the argument list. but it won't directly tell . 'var='. It gives detailed control over complex data structures. The answer in C is the pointer variable. As you may imagine this also could play havoc with use of arrays as arguments to C functions. 'var='. As a result. At one time or another most heavy Fortran users have needed this type of capability to efficiently manipulate complex data. If you will be running on parallel computers. and equivalents to the C pointer have been provided on most machines as extensions to Fortran 77. in many respects more powerful.

20) Why can't you associate Fortran pointers with any variable having the same type (as in C)? Maybe a cruel joke by the standards committee. aptr. target :: a. a and have a printed result of "1.i) which is identical in effect to b(i) = a*c(i. At any point in my program I can associate a pointer with a target with a statement such as: pa => a After this statement I can write a normal assignment such as: b(i) = pa*c(i. as a scientist. another level of protection against programming errors. 'a = '. b(1000).10) integer. pc1(:). pc2(:.:) The type of the pointer must match the type of the intended target. The first step in using Fortran pointers is to determine the variables to which you will need to associate pointers. I use the term portion because we will find that "pb" or "pc1" can be associated with a row or a column in "c" for the above examples. pointer :: pa.i) I could also write pa = 1. A pointer behaves a lot like an allocated variable. Now you define some pointers real. I want to understand the workings of my experimental apparatus (the computer performing numerical simulations). They must be given the TARGET attribute in a type statement. target :: i. to obtain maximum portability between different computers. I have mixed emotions on this restrictive approach to memory use. and at times tune it for maximum performance. I will gratefully write the vast majority of my new code within the constraints of the new Fortran 90 constructs. On the surface it behaves like an executable EQUIVALENCE statement. c(10.you the memory address of that variable. j(100). and the rank of the pointer must match the rank of the portion of the target to which it will be associated. but actually does quite a bit more. unused piece of memory. The pointer can be re-associated with another variable at any time: . More likely. because the actual size of the pointer object is not set until the pointer is associated with its target. to limit the probability that a typo will associate a pointer with the wrong variable. However. This may require a little more control over physical layout of my data structure. For example real. pb(:).23456" because changing "pa" changes "a".23456 print *. except you are allocating specific existing memory rather than a new. The use of isolated colons for pointers is mandatory. k(20. They refer to the same location in the computer's memory.

4).1:10) In this case we get the curious result that pb(1) is equivalent to c(5.1) is the same as c(4.3) with the same memory location as c(5. the ASSOCIATED intrinsic function.1) shares memory with c(3.3)). making associations with arrays or portions of arrays. and pb(1) is the same as b(101). and the NULLIFY statement. 'pa is currently associated with "a"' endif You can check to see if two pointers are associated with the same target using: if (associated(pa. . by using the logical valued intrinsic function ASSOCIATED. for which element pc2(1. target=a)) then print *. 'pa and aptr point to the same target' endif Look at the example associated. 4:6) results in pc2 behaving as an array with 3 rows and 3 columns ( real pc2(3. If I use the statement pb => b Any reference to "pb" is identical to a reference to "b". "pb" effectively has 1000 elements. Similar memory strides are involved when a rank two pointer is used to pick up a rectangular portion of a rank 2 array. on through pc2(3.2).4). The statement pc2 => c(3:5. Array Pointers Now we get to the interesting part. However. The compiler has hidden a skipping factor (stride) away in the definition of "pb" that can make your programming a little simpler than dealing with "c" directly.f and its results for more information on simple pointer association. if (associated(pa)) then print *.6).pa => b(1) or it can be forced to be disassociated from any variable with the NULLIFY statement: nullify (pa) You can inquire if a pointer is associated with any target. I could also do the following pb => c(5. 'pa is currently associated' endif For more details you can use the optional TARGET argument to see if the pointer is currently associated with a specific target. pc2(2. I can also write pb => b(101:200) In this case "pb" is an array with only 100 elements. pb(2) is equivalent to c(5. sequential elements in the object "pb" are actually spaced 10 real words apart in memory.1). if (associated(pa. target=aptr)) then print *. If you think about this. etc.

The statement allocate (pc1(20)) results in addition of memory for a 20 element real array. FUNC() CONTAINS REAL FUNCTION FUNC() POINTER :: FUNC . INTEGER. END FUNCTION END ! PTR is associated with TARG and is ! assigned an array specification of (5) ! TARG(1) has value of 5 ! Function result is a pointer STRUC module GGCM type record integer :: id integer :: dataLen integer. . Jobs like sorting can be made a little simpler. Confused? This is the easy part. pointer :: data integer :: ofs end type record contains end module . and some very powerful data structures can be created. . pointer :: pFile real*8. You are not likely to need pointers in the near future. When pointers are combined with ALLOCATE and derived data types.A second method exists for allocating space to a pointer. POINTER :: PTR(:) INTEGER. that can only be accessed through use of pointer "pc1". and try some programs of your own. take a look at the results of pointers. For more practice with array pointers. TARGET :: TARG(5) PTR => TARG PTR(1) = 5 PRINT *. You can use the ALLOCATE statement just as you would for an ALLOCATABLE array.f. but try to maintain some memory of this capability. It is very important for complex programming applications in just about any language. you have an excellent way to create and manipulate linked lists.

the ! standard syntax uses a percent sign (%) pear%id = 92316 pear%description = "juicy D'Anjou pear" pear%price = 0.id = 92316 pear.15 store_catalog(7)%id = 7831 store_catalog(7)%description = "milk bottle" store_catalog(7)%price = 1. store_catalog(12) . END TYPE'' TYPE item INTEGER id CHARACTER(LEN=200) description REAL price END TYPE ! ``RECORD /name/ variable'' becomes ``TYPE(name) variable'' TYPE(item) pear.15 store_catalog(7).price = 0.2 ! We can also manipulate the whole structure store_catalog(12) = pear print *.6.) to access fields of a record.price = 1. and an array of items named ``store_catalog'' RECORD /item/ pear. Here is an example of code using the non portable structure syntax: ! Declaring a structure named ``item'' and containing three fields: ! an integer ID. store_catalog(100) ! Instead of using a dot (. store_catalog(12) This code can easily be rewritten in the Fortran 90 syntax as following: ! ``STRUCTURE /name/ ..description = "juicy D'Anjou pear" pear. END STRUCTURE'' becomes ! ``TYPE name . store_catalog(100) ! We can directly access the fields of both variables pear. an description string and a floating-point price.description = "milk bottle" store_catalog(7).id = 7831 store_catalog(7). STRUCTURE /item/ INTEGER id CHARACTER(LEN=200) description REAL price END STRUCTURE ! Define two variables.2 ! Assignments of a whole variable do not change store_catalog(12) = pear print *.... under the name of “derived types”. this functionality was standardized in Fortran 90 with an different syntax. an single record of type ``item'' ! named ``pear''.2.1 STRUCTURE and RECORD Structures are user-defined aggregate data types.