46
Ngo Van Thanh, IOP 11/2011

Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Ngo Van Thanh, IOP 11/2011

Page 2: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Chương 3: Tóm lược một số ngôn ngữ lập trình (LT: 5, TH:5)

Ngôn ngữ lập trình Fortran

Ngôn ngữ lập trình C/C++

Page 3: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

3.1 Ngôn ngữ lập trình Fortran Tham khảo : http://www.liv.ac.uk/HPC/F90page.html

http://iop.vast.ac.vn/~nvthanh/cours/fortran/

So sánh tốc độ tính toán:

Tính toán song song (MPI)

functionality F90 F77 C++ C

Tính toán số 1 2 3 4

Tính toán dữ liệu song song 1 3 3 3

Dữ liệu trừu tượng 1 4 2 3

Lập trình hướng đối tượng 2 4 1 3

Lập trình hàm 1 4 2 3

Trung bình 1.2 3.4 2.2 3.2

Compiler Time (sec)

F90 1339.91

F77 1550.14

C++ 2797.00

Page 4: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Ví dụ: MODULE Triangle_Operations

IMPLICIT NONE

CONTAINS

FUNCTION Area(a,b,c)

REAL :: Area ! function type

REAL, INTENT(IN) :: a, b, c

REAL :: theta, height

theta=ACOS((a**2+b**2-c**2)/(2.0*a*b))

height=a*SIN(theta); Area=0.5*b*height

END FUNCTION Area

END MODULE Triangle_Operations !

PROGRAM Triangle

USE Triangle_Operations

IMPLICIT NONE

REAL :: x, y, z

PRINT*, 'Welcome, please enter the&

& lengths of the 3 sides.'

READ*, x, y, z

PRINT*,'Triangle''s area: ',Area(x,y,z)

END PROGRAM Triangle

Page 5: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

I.1. Lập trình Fortran 90

Kiểu mã nguồn:

Không phân biệt chữ hoa và chữ thường

Để dễ đọc chương trình nguồn :

Luôn sử dụng câu lện: IMPLICIT NONE.

Từ khoá, tên hàm… nên viết hoa

Các khối câu lệnh nên viết lùi vào 1 hoặc 2 dấu cách (space).

Tên của các chương trình con nên viết đầy đủ sau câu lệnh END.

Từ khoá cho các đối số là tuỳ chọn.

FUNCTION Area(a,b,c)

REAL :: Area ! function type

REAL, INTENT(IN) :: a, b, c

REAL :: theta, height

theta=ACOS((a**2+b**2-c**2)/(2.0*a*b))

height=a*SIN(theta); Area=0.5*b*height

END FUNCTION Area

Page 6: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Mã nguồn kiểu tự do: Độ dài tối da trên mỗi dòng : 132 ký tự.

Chú thích : ‘!’

Nỗi các dòng lệnh: `&'

Phân cách giữa các câu lệnh : ‘;’

theta=ACOS((a**2+b**2-c**2)

& /(2.0*a*b)) ! Angle \theta

PRINT*, 'Welcome, please enter the&

& lengths of the 3 sides.'

height=a*SIN(theta); Area=0.5*b*height

Mã nguồn kiểu cố định (F77) Chú thích : ‘!’ hoặc ‘c’ tại cột đầu tiên.

Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5

Nỗi các dòng lệnh: `&' tại cột thứ 6.

Độ dài tối da trên mỗi dòng : 72 ký tự; câu lệnh bắt đầu từ cột thứ 7

Page 7: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Tập ký tự:

Chữ và số:

a-z, A-Z, 0-9 and _

Các ký hiệu

Symbol Description Symbol Description

space = Equal

+ Plus > Greater than

- Minus < Less than

* Asterisk ( Left paren

/ Slash ) Right paren

. Period & Ampersand

, Comma % Percent

‘ Single quote ! Shriek

“ Double quote ? Question mark

: Colon $ Dolla

; semicolon

Page 8: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Chú thích:

Tất cả mọi ký tự phía sau dấu “!” đều là phần chú thích. !

! Function to calculate the area of a triangle

!

FUNCTION Area(a,b,c)

REAL, INTENT(IN) :: a, b, c ! Three side of the triangle

Dâu “!” nằm trong chuỗi ký tự đặt giữa dẫu “ ” hoặc ‘ ’ không phải là chú thích

PRINT*, “Thank you for your attention!!!”

Tên (biến, hằng số, hàm số…)

Bắt đầu phải là một ký tự (a-z).

Chỉ được sử dụng các chữ, số, dấu gạch dưới.

Độ dài tối đa là 32.

REAL :: 1x ! Not valid

CHARACTER(LEN=8) :: user_name ! Valid name

CHARACTER(LEN=8) :: user name ! Not valid

Page 9: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

I.2. Đối tượng dữ liệu:

Kiểu có sẵn (kiểu trong) Character: CHARACTER

Boolean : LOGICAL

Numeric :

REAL (and DOUBLE PRECISION)

INTEGER

COMPLEX

CHARACTER(LEN=20) :: fullname ! String

LOGICAL :: mathematician = .TRUE. ! Boolean : .TRUE. or .FALSE.

REAL :: area ! Real

DOUBLE PRECISION :: length ! Double precision

REAL*8 :: length ! Double precision

INTEGER :: index ! Integer

COMPLEX :: comp_num ! x + iy

Page 10: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Khai báo kiểu số và kiểu logic Syntax:

<type> [,<attribute-list>] :: <variable-list> [=<value>]

[…] : tuỳ chọn

<type> : các kiểu như : REAL, INTEGER, LOGICAL, CHARACTER

<attribute-list> : thuộc tính như : PARAMETER, SAVE, INTENT, POINTER, DIMENSION

=<value> : Giá trị ban đầu của biến số

REAL :: a, b, c

INTEGER :: i, j, k

REAL, DIMENSION(3) :: coords

DOUBLE PRECISION :: total

REAL, DIMENSION(0:9,0:9) :: latt2d, latt1d(14)

LOGICAL :: well_done, in_circle

Khai báo hằng số Syntax:

<type> ,PARAMETER :: <variable-list>=<value>

REAL, PARAMETER :: pi = 3.1416

INTEGER, PARAMETER :: N = 100, D = 3

Page 11: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

I.3. Biểu thức toán và phép gán

Các biểu thức 2.0*pi*radius ! Numeric valued

“Ngo Van ”//name ! Character valued (where variable name =“Thanh”)

width .GT. height ! Logical valued

Phép gán : = Gán giá trị của các biểu thức bên vế phải cho đối tượng bên vế trái.

a = b

theta=ACOS((a**2+b**2-c**2)/(2.0*a*b))

full_name = first_name//last_name

square = (a.EQ.b)

Toán tử số học ** : luỹ thừa ex.: volume = (4*pi*r**3)/3

* và / : nhân và chia ex.: area = (a*h)/2

+ và - : cọng và trừ ex.: a = b-c

Page 12: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Ví dụ:

PROGRAM Area_of_Circle IMPLICIT NONE REAL, PARAMETER :: pi = 3.14159 REAL :: r, area !

PRINT*, ‘please enter the radius’ READ*, r area = pi*r**2 PRINT*,’Circle''s area: ‘, area END PROGRAM Area_of_Circle

Exercise: write a program for calculating the volume of a sphere

Page 13: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Toán tử quan hệ

Kết quả là giá trị logic đúng hoặc sai: .TRUE. or .FALSE.

Toán từ logic

.NOT. : Cho giá trị phủ định của biểu thức.

.AND. : Cho giá trị .TRUE. nếu cả hai vế đều .TRUE.

.OR. : Cho giá trị .TRUE. nếu một trong hai hai vế có giá trị .TRUE.

.EQV. : .TRUE. Nếu hai vế giống nhau.

.NEQV. : .TRUE. Nếu hai vế khác nhau.

Letter Symbol Description

.GT. > greater than

.GE. >= greater than or equal to

.LE. <= less than or equal to

.LT. < less than

.NE. /= not equal to

.EQ. == equal to

Page 14: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

II.1. Câu lệnh điều khiển Lệnh rẽ nhánh.

IF statements

IF … THEN … ELSEIF … ELSE … ENDIF

Lệnh lặp

DO … ENDDO

Lệnh lựa chọn

SELECT CASE

Nhảy không điều kiện

GOTO

Page 15: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

IF Statement:

The basic form:

IF (<logical-expression>) <exec-stmt>

Nếu <logical-expression> là .TRUE. thì thực hiện <exec-stmt>

Ex:

IF (x > y) value = y

IF(I/=0 .AND. J.NE.0) r = a/(i*j)

Sơ đồ khối

IF (I > 12)

PRINT*, “I > 12”

!next statement

Page 16: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

IF có cấu trúc:

Dạng đơn giản:

IF (<logical-expression>) THEN

<exec-statements>

ENDIF

Ex:

IF (I > 12) THEN

PRINT*, “I > 12”

END IF

Sơ đồ khối

IF (I > 12) THEN

PRINT*, “I > 12”

ENDIF

Page 17: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

IF có thêm lệnh rẽ nhãnh ELSE :

IF (<logical-expression>) THEN

<exec-statements>

ELSE

<exec-statements>

ENDIF

Ex:

IF (I > 12) THEN

PRINT*, “I > 12”

ELSE

PRINT*, “I <= 12”

END IF

IF (I > 12) THEN

PRINT*,“I <= 12”

ENDIF

PRINT*, “I > 12”

Page 18: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

IF có thêm rẽ nhãnh kiểu ELSEIF :

IF (<logical-expression>) THEN

<exec-statements>

ELSEIF (<logical-expression>) THEN

<exec-statements>

ELSE

<exec-statements>

ENDIF

Ex:

IF (I > 12) THEN

PRINT*, “I > 12”

ELSEIF(I==12) THEN

PRINT*, “I = 12”

ELSE

PRINT*, “I < 12”

END IF

IF (I > 12) THEN

ELSEIF(I==12) THEN

ENDIF

PRINT*, “I > 12”

PRINT*, “I < 12” PRINT*, “I = 12”

I = 12

Page 19: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Vòng lặp DO :

Số vòng lặp xác định:

Ex:

DO I=1,100

PRINT*, I ! i is 1, 2, … 100; 100 iterations

ENDDO

Syntax:

DO <DO-var>=<expr1>,<expr2>,[,<expr3>]

<exec-stmts>

ENDDO

DO … WHILE Loops:

Vòng lặp không xác định:

Ex:

DO WHILE (a == b)

ENDDO

Page 20: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

SELECT CASE Construct:

SELECT CASE (I)

CASE(1); PRINT*, “I == 1”

CASE(2:9); PRINT*, “I >= 2 and I <= 9”

CASE(10:); PRINT*, “I >= 10”

CASE DEFAULT; PRINT*, “I <= 0”

END SELECT CASE

SELECT CASE(I)

PRINT*, “I == 1” PRINT*,

“I >= 2 and I <= 9” PRINT*, “I >= 10” PRINT*, “I <= 0”

END SELECT CASE

CASE(1) CASE(2:9) CASE(10:)

CASE DEFAULT

Page 21: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

II.2. Chương trình con có sẵn F90 có 113 chương trình con có sẵn.

Hàm chuyển đổi kiểu dữ liệu và các hàm toán học REAL(I)

INT(x)

NINT(x)

DBLE(a)

SIN(x)

ASIN(x)

SISH(x)

COS(x)

ACOS(x)

COSH(x)

TAN(x)

ATAN(x)

TANH(x)

ATAN2(y,x)

EXP(x)

LOG(x)

LOG10(x)

SQRT(x)

sine where x is in radians

arcsine

hyperbolic sine where x is in radians

cosine where x is in radians

arccosine

hyperbolic cosine where x is in radians

tangent where x is in radians

arctangent

hyperbolic tangent where x is in radians

arctangent of complex number (x, y)

e raised to the power x

natural logarithm of x

logarithm base 10 of x

the square root of x

Page 22: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

II.3. Vào ra dữ liệu

PRINT Statement: PROGRAM Outie

CHARACTER(LEN=*), PARAMETER long_name = “Llanfairphwyll...gogogoch”

REAL :: x, y, z

LOGICAL :: lacigol

x = 1; y = 2; z = 3

lacigol = (y .EQ. x) ! .TRUE.

PRINT*, long_name ! Llanfairphwyll...gogogoch

PRINT*, "Spock says ""illogical& ! Spock says “illogical Captain”

&Captain"" "

PRINT*, “x = ”, x , “y = ”, y, “z = ”, z ! x = 1.000 y = 2.000 z = 3.000

PRINT*, “Logical val: ”, lacigol ! x = Logical val: F

END PROGRAM Outie

READ Statement:

The simplest form of reading unformatted data from the standard input channel

READ*, long_name ! Llanfairphwyll...gogogoch

READ*, x, y, z ! 1.000 2.000 3.000

READ*, lacigol ! F

Page 23: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

III.1 Mảng Mảng có cấu trúc tương tự như ma trận.

Mảng 1 chiều có 15 phần tử

Mảng 2 chiều có kích thước là 4 5

1 2 3 … 13 14 15

1,1 1,2 1,3 1,4 1,5

2,1 2,2 2,3 2,4 2,5

3,1 3,2 3,3 3,4 3,5

4,1 4,2 4,3 4,4 4,5 Dim

ensi

on 1

Dimension 2

Page 24: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Các thuật ngữ trong mảng Ví dụ:

REAL*, DIMENSION(15) :: X

REAL*, DIMENSION(1:5, 1:3) :: Y, Z

Nếu cận dưới của mảng không khai báo thì sẽ lấy giá trị ngầm định là 1

Thuật ngữ:

rank : Số chiều của mảng.

X có rank 1, Y và Z có rank 2.

bounds : giới hạn trên và giới hạn dưới của mảng

X giới hạn dưới là 1 giới hạn trên là 15,

Y và Z ???

extent : Số phần từ trong mỗi chiều

X có extent là 15, Y và Z có extents 5 và 3.

size : tổng số phần từ của mảng.

shape : rank và extents, X có shape (/15/) Y và Z có shape (/5, 3/).

conformable : Hai mảng là conformable nếu chúng có shape giống nhau.

X và Y ???; Y và Z ???.

Page 25: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Khai báo Ví dụ về khai báo mảng:

REAL, DIMENSION(100) :: R

REAL, DIMENSION(1:10,1:10) :: S

REAL :: T(10,10)

REAL, DIMENSION(-10:-1) :: X

INTEGER, PARAMETER :: lda = 5

REAL, DIMENSION(lda) :: Y

REAL, DIMENSION(1+lda*lda,10):: Z

REAL, DIMENSION(0:10:2):: A

bounds có thể bắt đầu bởi bất kỳ số nào; giá trị ngầm định của biên dưới là 1

T : là dạng khái báo ngắn gọn

Câu hỏi:

INTEGER :: i = 3, j = 7

REAL, DIMENSION(1:20) :: A

Tham chiếu mảng nào dưới đây là đúng?

A(12) A(21) A(I) A(3.0) A(i*j)

Page 26: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Biểu diễn mảng Ví dụ:

REAL, DIMENSION(15) :: A

REAL, DIMENSION(-4:0,0:2) :: B

REAL, DIMENSION(5,3) :: C

REAL, DIMENSION(0:4,0:2) :: D

A(1) A(2) A(3) … A(13) A(14) A(15)

B(-4,0)

C(1,1)

D(0,0)

B(0,0)

C(5,1)

D(4,0)

B(-4,2)

C(1,3)

D(0,2)

B(0,2)

C(5,3)

D(4,2)

Page 27: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Thứ tự các phần tử trong mảng Không phụ thuộc vào thứ tự chỉ số mảng.

A(1,1), A(2,1), … A(4,1), A(2,1), A(2,2),… , A(3,4), A(4,4)

Tính toán trên toàn mảng A = 0.0

Các phần tử mảng được gán đồng thời.

B = C + D

Các mảng ở vế trái và vế phải đều là mảng đồng bộ.

Cách viết khác: B(:) = C(:) + D(:)

1,1 1,2 1,3 1,4

2,1 2,2 2,3 2,4

3,1 3,2 3,3 3,4

4,1 4,2 4,3 4,4

Page 28: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Thao tác trên từng phần tử của mảng

A(1) = 0.0

B(0,0) = A(3) + C(5,1)

Mảng con A(2:4) = 0.0

B(-1:0,1:2) = C(1:2,2:3) + 1.0

Ví dụ

DO i = 2, 15

A(i) = A(i) + A(i-1)

ENDDO

So sánh với: A(2:15) = A(2:15) + A(1:14)

Trường hợp thứ nhất:

A(i) = A(i) + A(i-1)+ … + A(2) + A(1)

Trường hợp thứ hai:

A(i) = A(i) + A(i-1)

Page 29: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Mảng động Mảng có số chiều xác định nhưng số các phần tử trong mỗi chiều là không xác định.

Khai báo:

Thuộc tính ALLOCATABLE :

INTEGER, DIMENSION(:), ALLOCATABLE :: ages

INTEGER, DIMENSION(:,:), ALLOCATABLE :: speed

Khởi tạo biến mảng động, sử dụng câu lệnh ALLOCATE

ALLOCATE(ages(1:10),STAT=ierr)

IF (ierr /= 0) THEN

PRINT*, “ages Allocation request denied”

ENDIF

Có thể khai báo nhiều mảng cùng một lúc:

ALLOCATE(A(1:20),B(0:4,1:5))

Giải phóng bộ nhớ các mảng động: DEALLOCATE(ages)

Câu lệnh kiểm tra: ALLOCATED

IF (ALLOCATED(ages)) DEALLOCATE(ages, STAT=ierr)

Page 30: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Ví dụ: PROGRAM sort_any_number

INTEGER, DIMENSION(:), ALLOCATABLE :: nums

INTEGER :: temp, I, K, n_to_sort, ierr

!

PRINT*, ‘How many numbers to sort’

READ*, n_to_sort

ALLOCATE( nums(n_to_sort), STAT=ierr)

IF (ierr .NE. 0) THEN

PRINT*, ‘nums: Allocation request denied’

STOP ! halts execution

END IF

PRINT*, ‘Type in ‘,n_to_sort, ‘ values one line at a time’

DO I = 1,n_to_sort

READ*, nums(I)

END DO

DO I = 1, n_to_sort-1

DO K = I+1, n_to_sort

IF(nums(I) > nums(K)) THEN

temp = nums(K) ! Store in temporary location

nums(K) = nums(I) ! Swap the contents over

nums(I) = temp

END IF

END DO

END DO

DO I = 1,n_to_sort

PRINT*, ‘Rank’, I, ‘value is ‘ , nums(I)

END DO

IF (ALLOCATED(nums)) DEALLOCATE(nums,STAT=ierr)

END PROGRAM sort_any_number

Page 31: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

IV. Chương trình con Thực hiện một số đoạn mã chương trình nào đó.

Fortran 90 có hai loại chương trình con:

SUBROUTINE

Kết quả được trả lại trên các đối số của chương trình con.

Sử dung lệnh CALL để gọi đến chương trình con.

FUNCTION

Tương tự như nhưng kết quả được trả lại trên tên của chương trình.

Tên hàm được đặt trong các biểu thức bên vế phải của phép gán.

Khi nào thì sử dụng chương trình con?

Loại chương trình con cần viết là SUBROUTINE hay FUNCTION ?

Số các đối số càng ít càng tốt.

Page 32: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Thân chương trình chính Tất cả các chương trình đều phải có cấu trúc chương trình chính:

[ PROGRAM [<main program name>]]

<declaration of local objects>

<executable stmts>

[CONTAINS

<internal procedure definitions>

END [PROGRAM [<main program name>]

Main Program example PROGRAM Main

IMPLICIT NONE

REAL x

INTRINSIC FLOOR !biggest INTEGER less than or equal to REAL number

READ*, x

PRINT*, FLOOR(x)

PRINT*, Negative(x)

CONTAINS

REAL FUNCTION Negative(a)

REAL, INTENT(IN) :: a

Negative(a) = -a

END FUNTION Negative

END PROGRAM Main

Page 33: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Subroutines SUBROUTINE <procname> [(<dummy args>)]

<declaration of dummy args>

<declaration of local objects>

<executable stmts>

END [SUBROUTINE [<procname>]]

Ví dụ PROGRAM Thingy

IMPLICIT NONE

CALL PrintOut(nums)

CONTAINS

SUBROUTINE PrintOut(numbers)

REAL, DIMENSION(:), INTENT(IN) :: numbers

PRINT*, ‘Here are the numbers ‘, numbers

END SUBROUTINE PrintOut

END PROGRAM Thingy

Page 34: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Functions

[<prefix>] FUNCTION <procname> [(<dummy args>)]

<declaration of dummy args>

<declaration of local objects>

<executable stmts, assignment of result>

END [FUNCTION [<procname>]]

Ví dụ PROGRAM Thingy

IMPLICIT NONE

PRINT*, F(a,b)

CONTAINS

REAL, FUNCTION F(x,y) ! FUNCTION F(x,y)

REAL, INTENT(IN) x,y ! REAL :: F

F = sqrt(x**+y**)

END FUNCTION F

END PROGRAM Thingy

Page 35: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Sự liên hợp đối số

CALL PrintOut(nums)

SUBROUTINE PrintOut(numbers)

Biến “nums” được gọi là đối số thực (actual argument).

Biến “numbers” là đối số hình thức (dummy argument )

Xét:

PRINT*, F(a,b)

FUNCTION F(x,y)

a tương ứng với x và b tương ứng với y.

Giá trị của đối số thực sẽ thay đổi nếu như đối số hình thức bị thay đổi trong chương trình con.

Số lượng đối số thực và đối số hình thức phải như nhau

Kiểu của mỗi đối số thực và đối số hình thức cũng phải phù hợp với nhau.

Page 36: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Biến địa phương

SUBROUTINE Madras(i, j)

INTEGER, INTENT(IN) :: i, j

REAL :: a

REAL, DIMENSION(i,j) :: x

a và x là các biến địa phương.

Chúng được khởi tạo mỗi khi chương trình con được gọi đến.

Khi chương trình con kết thúc thì các biến địa phương sẽ tự động được xoá bỏ.

Mảng x có kích thước khác nhau trong mỗi lần gọi chương trình con nếu như đối số i và j thay đổi.

Thuộc tính INTENT

INTENT(IN) : Chỉ được tham chiếu trong chương trình con

INTENT(OUT) : Chỉ được phép sử dụng sau khi được gán giá trị.

INTENT(INOUT) : Cho phép tham chiếu và gán giá trị.

Page 37: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

SUBROUTINE example(arg1,arg2,arg3)

REAL, INTENT(IN) :: arg1

INTEGER, INTENT(OUT) :: arg2

CHARACTER, INTENT(INOUT) :: arg3

REAL r

!

r = arg1*ICHAR(arg3)

! arg1 is unchanged within the procedure, arg3 is used.

arg2 = AINT(r)

! value of arg2 is not used until it has been assigned to

arg3 = CHAR(MOD(127,arg2))

! arg3 is re-assigned a value

END SUBROUTINE example

Page 38: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Biến toàn cục Xét ví dụ PROGRAM CalculatePay

IMPLICIT NONE

REAL :: Pay, Tax, Delta

INTEGER :: NumberCalcsDone = 0

Pay = … ; Tax = … ; Delta = …

CALL PrintPay(Pay, Tax)

Tax = NewTax(Tax, Delta)

CONTAINS

SUBROUTINE PrintPay(Pay, Tax)

REAL, INTENT(IN) :: Pay, Tax

REAL :: TaxPaid

TaxPaid = Pay*Tax

PRINT*, TaxPaid

NumberCalcsDone = NumberCalcsDone + 1

END SUBROUTINE PrintPay

!

REAL FUNCTION NewTax(Tax, Delta)

REAL, INTENT(IN) :: Tax, Delta

NewTax = Tax Delta*Tax

NumberCalcsDone = NumberCalcsDone + 1

END FUNCTION NewTax

END PROGRAM CalculatePay

NumberCalcsDone là biến toàn cục

Page 39: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Phạm vi tác dụng của tên biến

Xét ví dụ

PROGRAM Proggie

IMPLICIT NONE

REAL :: A, B, C

!

CALL SUB(A)

CONTAINS

SUBROUTINE Sub(D)

REAL :: D

REAL :: C

!

C = A**3

D = D**3 + C

B = C

END SUBROUTINE Sub

END PROGRAM Proggie

Page 40: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Thuộc tính SAVE

SUBROUTINE Barmy(arg1,arg2)

INTEGER, SAVE :: NumInvocation = 0

NumInvocation = NumInvocation + 1

END SUBROUTINE Barmy

NumInvocation được giữ lại giá trị của nó và có thể sử dụng cho lần gọi

tiếp theo.

SUBROUTINE polo(x,y)

IMPLICIT NONE

INTEGER :: mint, neck_jumper

SAVE

REAL :: stick, car

END SUBROUTINE polo

SAVE : nằm riêng trên một dòng.

Tất cả các biến địa phương trong chương trình con đều có thuộc tính SAVE: mint, neck_jumper và stick, car.

Thuộc tính SAVE không có ý nghĩa trong chương trình chính.

Page 41: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Đối số mảng Mảng có shape tường minh

INTEGER, DIMENSION(8,8), INTENT(IN) :: explicit_shape

PROGRAM Main

IMPLICIT NONE

INTEGER, DIMENSION(8,8) :: A1

INTEGER, DIMENSION(64) :: A2

INTEGER, DIMENSION(16,32) :: A3

...

CALL subby(A1)

CALL subby(A2) ! non conforming

CALL subby(A3(::2,::4))

CALL subby(RESHAPE(A2, (/8,8/)))

CONTAINS

SUBROUTINE subby(explicit_shape)

INTEGER, DIMENSION(8,8) :: explicit_shape

END SUBROUTINE subby

END PROGRAM Main

Page 42: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Mảng có shape giả định (assumed-shape)

PROGRAM Main

IMPLICIT NONE

...

REAL, DIMENSION(40) :: X

REAL, DIMENSION(40,40) :: Y

...

CALL gimlet(X,Y)

CALL gimlet(X(1:39:2),Y(2:4,4:4))

CALL gimlet(X(1:39:2),Y(2:4,4)) ! Invalid, Y is 1D array.

CONTAINS

SUBROUTINE gimlet(a, b)

REAL, INTENT(IN) :: a(:), b(:,:)

END SUBROUTINE gimlet

END PROGRAM Main

Page 43: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Mảng tự động

PROGRAM Main

IMPLICIT NONE

INTEGER,DIEMSION(10,10) :: IX, IY

...

CALL Use_Bus_Riot(IX,2,3)

CALL Use_Bus_Riot(IX,7,2)

CONTAINS

SUBROUTINE Use_Bus_Riot(A, M, N)

INTEGER,INTENT(IN) :: M,N

INTEGER,INTENT(INOUT) :: A(:,:)

REAL :: A1(M,N) ! automatic

REAL :: A2(SIZE(A1,1),SIZE(A,2)) ! ditto

REAL :: A3(A(1,1),A(1,1)) ! automatic

END SUBROUTINE Use_Bus_Riot

END PROGRAM Main

Page 44: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Hàm kiểu mảng

PROGRAM proggie

IMPLICIT NONE

INTEGER, PARAMETER :: m =6

INTEGER, DIMENSION(M,M) :: im1,im2

...

IM2 = funnie(im1,1)

CONTAINS

FUNCTION funnie(ima,scal)

INTEGER, INTENT(IN) :: ima(:,:)

INTEGER, INTENT(IN) :: scal

INTEGER :: funnie(SIZE(ima,1),SIZE(ima,2))

funnie(:,:) = ima(:,:)*scal

END FUNCTION funnie

END PROGRAM proggie

Page 45: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Hàm đệ quy (Recursive Function) PROGRAM Mayne

IMPLICIT NONE

PRINT*, fact(12)

CONTAINS

RECURSIVE FUNCTION fact(N) RESULT(N_fact)

INTEGER, INTENT(IN) :: N

INTEGER :: N_Fact

IF(N > 0) THEN

N_Fact = N*fact(N-1)

ELSE

N_Fact = 1

END IF

END FUNCTION fact

END PROGRAM Mayne

Chương trình tính giai thừa

Ví dụ 4!:

4! bằng 4 3!

3! bằng 3 2!

2! bằng 2 1!

1! bằng 1 0!

0! = 1

Page 46: Ngo Van Thanh, IOP 11/2011nvthanh/cours/comp/Bai_Giang_P1.03.pdf · Nhãn lệnh được đặt từ cột thứ 2 đến cột thứ 5 Nỗi các dòng lệnh: `&' tại cột thứ

Thủ tục đệ quy (Recursive Subroutine)

PROGRAM Mayne

IMPLICIT NONE

CONTAINS

RECURSIVE SUBROUTINE Factorial(N,Result)

INTEGER, INTENT(IN) :: N

INTEGER, INTENT(INOUT) :: Result

IF(N > 0) THEN

CALL Factorial(N-1,Result)

ELSE

Result = 1

END IF

END SUBROUTINE fact

END PROGRAM Mayne

Ví dụ 4!:

4! bằng 4 3!

3! bằng 3 2!

2! bằng 2 1!

1! bằng 1 0!

0! = 1