Fortran - Mảng

Mảng có thể lưu trữ một tập hợp tuần tự có kích thước cố định của các phần tử cùng loại. Mảng được sử dụng để lưu trữ một tập hợp dữ liệu, nhưng thường hữu ích hơn nếu coi một mảng là một tập hợp các biến cùng kiểu.

Tất cả các mảng bao gồm các vị trí bộ nhớ liền kề. Địa chỉ thấp nhất tương ứng với phần tử đầu tiên và địa chỉ cao nhất cho phần tử cuối cùng.

Số (1) Số (2) Số (3) Số (4)

Mảng có thể là một chiều (như vectơ), hai chiều (như ma trận) và Fortran cho phép bạn tạo mảng tối đa 7 chiều.

Khai báo Mảng

Mảng được khai báo với dimension thuộc tính.

Ví dụ, để khai báo mảng một chiều có tên là số, gồm các số thực có chứa 5 phần tử, bạn viết:

real, dimension(5) :: numbers

Các phần tử riêng lẻ của mảng được tham chiếu bằng cách chỉ định các chỉ số con của chúng. Phần tử đầu tiên của một mảng có một chỉ số con của một. Mảng số chứa năm biến thực –numbers (1), number (2), number (3), number (4) and number (5).

Để tạo mảng hai chiều 5 x 5 gồm các số nguyên có tên là ma trận, bạn viết:

integer, dimension (5,5) :: matrix

Bạn cũng có thể khai báo một mảng với một số giới hạn dưới rõ ràng, ví dụ:

real, dimension(2:6) :: numbers
integer, dimension (-3:2,0:4) :: matrix

Gán giá trị

Bạn có thể chỉ định giá trị cho từng thành viên, chẳng hạn như,

numbers(1) = 2.0

hoặc, bạn có thể sử dụng một vòng lặp,

do i  =1,5
   numbers(i) = i * 2.0
end do

Các phần tử mảng một chiều có thể được gán trực tiếp các giá trị bằng cách sử dụng một ký hiệu viết tay ngắn, được gọi là hàm tạo mảng, như,

numbers = (/1.5, 3.2,4.5,0.9,7.2 /)

please note that there are no spaces allowed between the brackets ‘( ‘and the back slash ‘/’

Thí dụ

Ví dụ sau đây minh họa các khái niệm đã thảo luận ở trên.

program arrayProg

   real :: numbers(5) !one dimensional integer array
   integer :: matrix(3,3), i , j !two dimensional real array
   
   !assigning some values to the array numbers
   do i=1,5
      numbers(i) = i * 2.0
   end do
   
   !display the values
   do i = 1, 5
      Print *, numbers(i)
   end do
   
   !assigning some values to the array matrix
   do i=1,3
      do j = 1, 3
         matrix(i, j) = i+j
      end do
   end do
   
   !display the values
   do i=1,3
      do j = 1, 3
         Print *, matrix(i,j)
      end do
   end do
   
   !short hand assignment
   numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
   
   !display the values
   do i = 1, 5
      Print *, numbers(i)
   end do
   
end program arrayProg

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

2.00000000    
 4.00000000    
 6.00000000    
 8.00000000    
 10.0000000    
         2
         3
         4
         3
         4
         5
         4
         5
         6
 1.50000000    
 3.20000005    
 4.50000000    
0.899999976    
 7.19999981

Một số thuật ngữ liên quan đến mảng

Bảng sau đây đưa ra một số thuật ngữ liên quan đến mảng:

Kỳ hạn Ý nghĩa
Cấp Nó là số thứ nguyên mà một mảng có. Ví dụ: đối với mảng có tên là ma trận, hạng là 2 và đối với mảng có tên là số, hạng là 1.
Mức độ Nó là số phần tử dọc theo một thứ nguyên. Ví dụ, số mảng có phạm vi 5 và ma trận có tên mảng có phạm vi 3 ở cả hai chiều.
Hình dạng Hình dạng của mảng là mảng số nguyên một chiều, chứa số phần tử (phạm vi) trong mỗi chiều. Ví dụ, đối với ma trận mảng, hình dạng là (3, 3) và số mảng là (5).
Kích thước Nó là số phần tử mà một mảng chứa. Đối với ma trận mảng, nó là 9 và đối với số mảng, nó là 5.

Chuyển Mảng sang Thủ tục

Bạn có thể truyền một mảng cho một thủ tục làm đối số. Ví dụ sau thể hiện khái niệm -

program arrayToProcedure      
implicit none      

   integer, dimension (5) :: myArray  
   integer :: i
   
   call fillArray (myArray)      
   call printArray(myArray)
   
end program arrayToProcedure


subroutine fillArray (a)      
implicit none      

   integer, dimension (5), intent (out) :: a
   
   ! local variables     
   integer :: i     
   do i = 1, 5         
      a(i) = i      
   end do  
   
end subroutine fillArray 


subroutine printArray(a)

   integer, dimension (5) :: a  
   integer::i
   
   do i = 1, 5
      Print *, a(i)
   end do
   
end subroutine printArray

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

1
2
3
4
5

Trong ví dụ trên, chương trình con fillArray và printArray chỉ có thể được gọi với các mảng có kích thước là 5. Tuy nhiên, để viết các chương trình con có thể được sử dụng cho các mảng có kích thước bất kỳ, bạn có thể viết lại nó bằng kỹ thuật sau:

program arrayToProcedure      
implicit  none    

   integer, dimension (10) :: myArray  
   integer :: i
   
   interface 
      subroutine fillArray (a)
         integer, dimension(:), intent (out) :: a 
         integer :: i         
      end subroutine fillArray      

      subroutine printArray (a)
         integer, dimension(:) :: a 
         integer :: i         
      end subroutine printArray   
   end interface 
   
   call fillArray (myArray)      
   call printArray(myArray)
   
end program arrayToProcedure


subroutine fillArray (a)      
implicit none      
   integer,dimension (:), intent (out) :: a      
   
   ! local variables     
   integer :: i, arraySize  
   arraySize = size(a)
   
   do i = 1, arraySize         
      a(i) = i      
   end do  
   
end subroutine fillArray 


subroutine printArray(a)
implicit none

   integer,dimension (:) :: a  
   integer::i, arraySize
   arraySize = size(a)
   
   do i = 1, arraySize
     Print *, a(i)
   end do
   
end subroutine printArray

Xin lưu ý rằng chương trình đang sử dụng size hàm lấy kích thước của mảng.

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

1
2
3
4
5
6
7
8
9
10

Phần mảng

Cho đến nay chúng ta đã tham chiếu đến toàn bộ mảng, Fortran cung cấp một cách dễ dàng để tham chiếu một số phần tử hoặc một phần của mảng, bằng cách sử dụng một câu lệnh duy nhất.

Để truy cập một phần mảng, bạn cần cung cấp giới hạn dưới và giới hạn trên của phần đó, cũng như một khoảng cách (gia số), cho tất cả các kích thước. Ký hiệu này được gọi làsubscript triplet:

array ([lower]:[upper][:stride], ...)

Khi không có giới hạn dưới và giới hạn trên được đề cập, nó sẽ mặc định theo phạm vi bạn đã khai báo và giá trị bước đi mặc định là 1.

Ví dụ sau thể hiện khái niệm -

program arraySubsection

   real, dimension(10) :: a, b
   integer:: i, asize, bsize
   
   a(1:7) = 5.0 ! a(1) to a(7) assigned 5.0
   a(8:) = 0.0  ! rest are 0.0 
   b(2:10:2) = 3.9
   b(1:9:2) = 2.5
   
   !display
   asize = size(a)
   bsize = size(b)
   
   do i = 1, asize
      Print *, a(i)
   end do
   
   do i = 1, bsize
      Print *, b(i)
   end do
   
end program arraySubsection

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
0.00000000E+00
0.00000000E+00
0.00000000E+00
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010

Các chức năng nội tại của mảng

Fortran 90/95 cung cấp một số quy trình nội tại. Chúng có thể được chia thành 7 loại.

  • Phép nhân vectơ và ma trận

  • Reduction

  • Inquiry

  • Construction

  • Reshape

  • Manipulation

  • Location