!
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
!
!         <<<<<---------------------------------------------->>>>>
!         <<<<<      6. S P E C I F I C A T I O N            >>>>>
!         <<<<<         S T A T E M E N T S                  >>>>>
!         <<<<<---------------------------------------------->>>>>
!
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! IMPLICIT TYPING

! Strong typing 
! =============
! When an entity is encountered in a statement without its TYPE 
! having been declared will cause an error.
!
! In Fortran 90, the default is to assign variables that begin with :
!
! I-N           : integer type
! A-H and O-Z   : real type
!
! To work under weal-typing conditions is EXTREMELY DANGEROUS. 
! For example, when a variable is misspelt the compiler will treat it
! as a new variable instead of giving an error!
!
! The command IMPLICIT is available to deal with these situations
!
! The general syntax is  
! 
! IMPLCIT type (letter-spec-list) [,type(letter-spec-list)] ...
!
! Examples
!

  IMPLICIT NONE              ! STRONG TYPING 
  
  IMPLICIT INTEGER (A-G)     ! All variables whose name begins with 
                             ! a letter in the range A-G will be 
                             ! assigned the type integer

  IMPLICIT COMPLEX (Q-R)     ! All variables whose name begins with 
                             ! a letter in the range Q-R will be 
                             ! assigned the type complex
                             
  IMPLICIT REAL (I-U)        ! All variables whose name begins with 
                             ! a letter in the range I-U will be 
                             ! assigned the type real

  IMPLICIT REAL (SELECTED_REAL_KIND(10)) (I-U)        

                             ! All variables whose name begins with 
                             ! a letter in the range I-U will be 
                             ! assigned the type real of specified kind

  IMPLICIT TYPE(ENTRY) (U,X-Z) 

                             ! All variables whose name begins with 
                             ! U and with a letter in the range X-Z will 
                             ! be assigned the DERIVED type ENTRY
                             ! (defined beforehand in the program)

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! IT IS RECOMMENDED TO WORK UNDER THE STRONG TYPING RULE !!
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


!=======================================================================
! DECLARING ENTITIES OF DIFFERENT SHAPES
!
! We have seen so far declarations of the type 
!

  INTEGER A,B
  REAL, DIMENSION(70) :: X
  REAL, DIMENSION(100) :: Z,Y
  INTEGER, DIMENSION(5,8) :: Q

! Whether or not the ATTRIBUTE DIMENSION is present or not, arrays 
! may be declared by placing the relevant shape information after 
! the name of the array

  INTEGER A, B, Q(5,8)
  REAL    X, Z(100), Y(100)

! The dimension attribute can be present to provide a default shape 
! that will be ignored if explicit shapes are specified
!

  REAL, DIMENSION(100) :: A, B, C, D(80), W(100,100)

    
!=======================================================================
! NAMED CONSTANTS
!
! Inside a program we often need to define constants or sets of 
! constants that must not be modified
!
! one might need for example the speed of light 

 C = 2.99792548
 
! However, these constants must be protected against accidental 
! modification. The PROGRAM attribute (and statement, which is NOT 
! recommended) exist for this purpose:
!

 REAL, PARAMETER :: C = 2.99792548

! Then C is a "NAMED CONSTANT" and may never appear on the l.h.s of 
! an assignment statement, or bne read from a file
!

! It is possible to define several constant in one single statement
!

 INTEGER, PARAMETER :: LENGTH=10, LONG=SELECTED_REAL_KIND(12)
 REAL, PARAMETER    :: LSQ = LENGTH**2

! It is possible to define named constants of the array type

 REAL, DIMENSION(3), PARAMETER :: A = (/ 0.6327, 8.5413, 1.0192 /)

! And also named constants of derived type.
! For example, if the derived type POSN have been defined

  TYPE POSN 
      REAL X,Y
      INTEGER N
  END TYPE POSN
 
! one may define a named constant of this type as follows

 TYPE(POSN) Q                            ! Q of type POSN, not a
                                         ! parameter
                                         
 TYPE(POSN), PARAMETER :: Q = POSN( 1.0293, 3.2730, 0 )  

!
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! INITIAL VALUES FOR VARIABLES
!
! Variables may be declared and initialized at the same time  

  REAL    :: A = 1.72357
  INTEGER :: Q = 178
  REAL, DIMENSION(3) :: Z = (/ 0.56, 0.516, -0.12 /)

! An alternative way to specify initial values for variables is 
! through the DATA statement
!
! DATA object-list /value-list/ [[,] object-list/value-list/] ..
!
! Example
!
  REAL A,B,C,X,Z
  DATA A,B,C/1.72,9.83,0.0/, X,Z/0.0,0.0/ 

! Constants which repeat may be written once and combined with a 
! scalar *repeat count* which may be a named or literal constant

  INTEGER I,J,JK
  DATA I,J,K/3*0/  
  DATA I,J,K/0,0,0/

  INTEGER, PARAMETER :: LENGTH = 100
  REAL, DIMENSION(LENGTH) :: Q
  DATA Q(1:LENGTH)/LENGTH*0/

! this is equivalent to
!

  DO I=1,LENGTH
      Q(I) = 0.0
  END DO
  
  
! the first example means that we are assigning three times zero. In 
! the second example we are assigning 100 times zero. 
!

!***********************************************************************
! Array initialization
!
! Arrays may be initialized in three different ways:
!
! Let us consider an array declared as 
! 

   REAL A(5,5)

! equivalent to 

   REAL, DIMENSION(5,5) :: A

!========== First way - all elements at once
!

  DATA A/25*1.0/       ! if all elements are initialized to the same 
                       ! value


!========== Second way - individual elements 
!

  DATA A(1,1), A(3,1), A(1,2), A(3,3) / 2*1.0, 2*2.0 /
!
! equivalent to
!  
  DATA A(1,1), A(3,1), A(1,2), A(3,3) / 1.0, 1.0, 2.0, 2.0 /

  DATA A(2:5,4) / 4*1.0 / 

!
!========== Third way - implied do loops 
!

  DATA (( A(I,J),I=1,5), J=1,5 )/25*0.0/
  DATA (( A(I,J),I=1,5,2), J=1,5 )/15*0.0/
  

! An object of derived type my also appear in a DATA statement
!

  TYPE(POSN) :: POSITION1, POSITION2
  DATA POSITION1/POSN(1.367,-0.627,1)/, POSITION2%X/0.728/

! the equivalent for a variable of intrinsic data type

  DATA X/1.0/

  
  
    
   
   

   
      



                                                 

  
