Sách Giải

https://sachgiai.com

Kiểu dữ liệu mảng (array) trong Pascal

Một mảng dữ liệu gồm một số hữu hạn phần tử có cùng kiểu gọi là kiểu cơ bản. Số phần tử của mảng được xác định ngay từ khi định nghĩa ra mảng. Mỗi phần tử của mảng được truy nhập trực tiếp thông qua tên mảng cùng với chỉ dẫn truy nhập được để giữa hai ngoặc vuông [ ].
1. KHÁI NIỆM
Chúng ta đã làm quen với các kiểu dữ liệu đơn giản là các kiểu vô hướng (integer, char, boolean, real, kiểu liệt kê) và đoạn con. Trong Pascal tồn tại các kiểu dữ liệu có cấu trúc là các kiểu dữ liệu được tạo ra tư các phần tử có kiểu dữ liệu đơn giản bằng một cách nào đó. Chúng được đặc trưng bằng kiểu dữ liệu của các phần tử và điều quan trọng hơn cả là phương pháp cấu thành dữ liệu mới (điều đó cũng có nghĩa là phương pháp truy nhập vào kiểu dữ liệu có cấu trúc). Tính có cấu trúc của dữ liệu là một đặc trưng của ngôn ngữ lập trình có cấu trúc.
Pascal có tất cả 4 kiểu dữ liệu có cấu trúc mà chúng ta sẽ lần lượt nghiên cứu: mảng (ARRAY), tập (SET), bản ghi (RECORD) và tệp (FILE).

2. ĐỊNH NGHĨA: KIỂU DỮ LIỆU MẢNG (ARRAY)
Một mảng dữ liệu gồm một số hữu hạn phần tử có cùng kiểu gọi là kiểu cơ bản. Số phần tử của mảng được xác định ngay từ khi định nghĩa ra mảng. Mỗi phần tử của mảng được truy nhập trực tiếp thông qua tên mảng cùng với chỉ dẫn truy nhập được để giữa hai ngoặc vuông [ ]. Ví dụ: A[5] là phần tử thứ 5 của mảng A.
Định nghĩa kiểu mảng T có kiểu của các phần tử KPT, có kiểu chỉ dẫn KCD để hướng dẫn cách tổ chức mảng cũng như cách truy nhập vào các phần tử mảng được viết trong Pascal như sau:
TYPE
     T = ARRAY[KCD] OF KPT
Khi đó việc khai báo một biến A có kiểu là T có thể được viết như sau:
VAR
     A: T ;
Hoặc ta có thể khai báo trực tiếp biến A cùng với kiểu cùng mảng trong phần khai báo biến khi không có định nghĩa trong phần TYPE:
     VAR
          A = ARRAY [Kiểu_chỉ_dẫn] of kiểu_phần_tử.
Chúng ta hãy xét một số ví dụ định nghĩa và khai báo sau:

■ Ví dụ 1:
  TYPE
       MAININT = ARRAY [1..20] OF INTEGER ;
       MANGCHAR = ARRAY [1..20] OF CHAR ;
       THU = (CHUNHAT, HAI, BA, TƯ, NAM, SAƯ, BAY) ;
   VAR
       MI, MJ, MK: MANGINT ;
       X, Y: MANGCHAR ;
       Ml, M2: ARRAY [-10.. 10] OF REAL ;
       M3: ARRAY ['A'..'Z'] OF INTEGER ;
       TUAN: ARRAY [THU] OF BOOLEAN ;
MANGINT và MANGCHAR là hai kiểu mảng gồm 20 phần tử được đánh số thứ tự từ 1 đến 20 thông qua kiểu chỉ dẫn là một đoạn con các số nguyên 1..20. Các phần tử MANGINT có kiểu là số nguyên, còn các phần tử của MANGCHAR có kiểu là các kí tự, MI, MJ, MK là các biến có kiểu là MANGINT.
Còn M1 và M2 là hai biến được định nghĩa kiểu luôn khi khai báo. Đây là hai biến mảng gồm 21 phần tử là các số nguyên, được đánh số từ -10 đến 10.
M3 là một biến mảng gồm 26 số nguyên đánh số qua các chỉ dẫn là các chữ cái từ 'A' cho đến ‘Z’.
TUAN là một mảng gồm 7 phần tử kiểu Boolean, các phần tử được đánh dấu qua chỉ dẫn là tên của 7 ngày trong tuần.
Một điều lưu ý là khi khai báo mảng, kiểu chỉ dẫn chỉ có thể là các kiểu đơn giản: kiểu đoạn con của các loại dữ liệu vô hướng đếm được như kí tự (như biến M3), số nguyên (thí dụ đoạn con integer như các kiểu MANGINT, MANGCHAR). Kiểu Boolean. Kiểu chỉ dẫn không được là kiểu không đếm được như REAL. Nghĩa là không được viết:
                X: ARRAY [REAL] OF INTEGER ;
Ngoài ra, do giới hạn của vùng nhớ dành cho dữ liệu, số lượng phần từ của một mảng cũng bị hạn chế tùy thuộc vào kích thước của kiểu dữ liệu của các phần tử. Vì lí do này ta không thể khai báo mảng dạng:
                 X: ARRAY [INTEGER] OF INTEGER ;
dù INTEGER là kiêu vó hướng đếm được. Nhưng ta có thế khai báo như sau:
                 X: ARRAY [BYTE] OF INTEGER ;
Việc truy nhập vào một phần tử nào đó của mảng được thực hiện qua tên biến mảng, theo sau là giá trị chỉ dẫn để trong ngoặc vuông như:
                 TUAN[HAI]:= TRUE ;
                 M3['X'|:= 5 ;
Do thời gian truy nhập vào một phần tử của mảng không phụ thuộc vào giá trị của chỉ dẫn riêng nên câu trúc mảng thuộc kiểu cấu trúc truy nhập trực tiếp.
PASCAL không cho phép chúng ta nhập dữ liệu trực tiếp vào một mảng mà phải nhập giá trị của từng phần tử của từng mảng.

■ Ví dụ 2:
Để nhập dữ liệu vào mảng M1 ta phải viết như sau:
Writeln (’Nhập số liệu:’) ;
For I:= -10 to 10 do
      Begin
          Write ('Ml[', I,’] =') ;
           Readln (M1[I]) ;
       End ;
Trong ví dụ này ta cần thêm một biến i có kiểu là INTEGER làm biến chỉ dẫn.

3. THAO TÁC TRÊN MẢNG
Khác với các kiểu dữ liệu định- sẵn, trên kiểu dữ liệu mảng các thao tác đều do người lập trình tự xây dựng dựa trên các thao tác sẵn có trên các phần tử của mảng. PASCAL chỉ cho phép chúng ta gán giá trị của một biến mảng này cho một biến mảng khác có cùng kiểu:
                                         MI:= KJ ;
trong đó MI, MJ là hai mảng khai báo trong ví dụ 1 ở trên.

■ Ví dụ 3:
Để có thể xây dựng phép cộng 2 mảng cùng kiểu ta làm như sau:
                    For I:= 1 to 20 do MK[I]:= MI[I] + MJ[I] ;

■ Ví dụ 4:
Để tìm kiếm phần tử lớn nhất trong một mảng A các số nguyên ta làm như sau:
     CONST
          SPT =10;
     TYPE
          MA = ARRAY [1..SPT] OF INTEGER ;
     VAR
          PTMAX: INTEGER ; {Dùng để lưu giá trị lớn nhất trong A}
          A: MA ;
     FUNCTION MAX (A: MA ; N: INTEGER): INTEGER ;
     (hàm MAX trả về giá trị của pt lớn nhất trong A}
     VAR
          M, I: INTEGER ;
     BEGIN
          M:= A[l] (Giả sử {1} là MAXI
     FOR I:= 2 TO N DO
          IF A[I] > M THEN M:= A[I] ;
     END ;
     BEGIN
       ... {nhập số liệu của mảng A}
          PTMAX:= MAX(A. SPT) ;
       …
    END

■ Ví dụ 5:
Để tìm kiếm phần tử X trong một mảng A các số nguyên ta làm như sau:
      CONST
           SPT = 10 ;
      TYPE
           MA = ARRAY [1..SPT] OF INTEGER ;
      VAR
           VT_X, S: INTEGER ; {Dùng để lưu giá trị lớn nhất trong. A}
           A: MA ;
      FUNCTION TIM_X (X: INTEGER ;
           A: MA. N > INTEGER): INTEGER ;
      {Hàm TIM_X trả về vị trí của X trong A nếu TIM_X <> 0.
        Nếu TIM_X = 0, < không nằm trong A},
        VAR
              M, I: INTEGER ;
        BEGIN
              M:= 0 ; {Giả sử A[l] là MAX)
              I:= 1 ;
              While (I <= N) AND (m = 0) do
                    IF ATI] = X THEN M:= I ;
                    TIM_X:= M ;
               END ;
        BEGIN
             ... {Nhập sô' liệu của mảng A}
            VT-X:= TIM_X (X, A, SPT) ;
        END.
 
Tổng quát, để tìm phần tử X thỏa mãn điều kiện trong mảng A ta có thể làm như sau:
       CONST
            SPT = 10 ;
       TYPE
            MA = ARRAY [1..SPT] OF INTEGER ;
       VAR
            VT_X, X: INTEGER ; {Dùng để lưu giá trị lớn nhất trong A}
            A: MA ;
            FUNCTION TIM_THEO_DK (VAR X: INTEGER ; A: MA;
            N: INTEGER): INTEGER ;
       {Tham số X trả về giá trị của Phần tử thỏa điêu kiện}.
        Hàm TIM_X trả về giá trị của Phần tử thỏa điều kiện,
        Hàm TIMLX trả về vị trí của X trong A nếu TIM_X <> 0.
        Nếu TIM_X = 0, X không nằm trong A}
        VAR
              M, I: INTEGER ;
        BEGIN
              M:= 0 {Giả sử A[l] là MAX}
              I:= 1 ;
              WHILE (I <= N) ANMD (M = 0) DO
                    If Đieu_kien = TRUE THEN
                        Begin
                            M:= I ;
                            X:= A[I] ;
                        End ;
                    TIM_X:= M ;
            END ;
       BEGIN
            ... {Nhập số liệu của mảng A}
           VT_X:= TIM_X (X, A, SPT);
       END.
 
4. MẢNG NHIỀU CHIỀU
Kiểu phần tử của mảng không bị hạn chế nhiều như kiểu chỉ dẫn. Nó còn có thể là các kiểu cấu trúc. Ví dụ sau cho thấy việc khai báo một mảng có các phần tử cũng là mảng.

■ Ví dụ 6:
     TYPE
          PT = ARRAY fl..51 OF REAL ; {Pt: Kiểu phần tử}
     VAR
          MPT: ARRAY [1 .31 OF PT ; {MPT: Mang phần tử}
Hoặc viết một lần như sau:
     VAR
          MPT: ARRAY II..31 OF ARRAY [1..5] OF REAL
Hoặc thường được viết gọn lại:
     VAR
          MPT: ARRAY [1 .3, 1..5] OF REAL ;
MPT được định nghĩa như trên chính là ma trận 2 chiều 3 hàng và 5 cột.
Việc truy nhập đôi với màng ó định nghĩa phức tạp như MPT được tiến hành qua hai cách:
+ Qua hai lần đóng mở ngoặc vuông. Thí dụ MPT[3][5] biểu diễn phần tử cuối cùng của mảng MPT.
+ Hoặc thường được viết đơn giản trong một ngoặc vuông với các chỉ dẫn cách nhau bằng dấu phẩy: MPT[3, 5] ;
Cách viết MPT[I][J] và MPT[I,J] là tương đương nhau. Mảng được định nghĩa như trên có thể hiểu là ma trận nhiều chiều. Phần tử MPT[I,J] sẽ là phần tử hàng I, cột thứ J của MPT.

■ Ví dụ 7:
Chương trình nhân hai ma trận vuông cấp N: C = A * B
Phần tử của ma trận tích được tính theo công thức:
Cij=ak=1    N   0 aikbkj

     PROGRAM NHAN_MA_TRAN ;
     CONST
          N = 5 ;
     TYPE
          MATRAN = ARRAY [1..N, 1..N] OF INTEGER ;
     VAR
         A, B, C: MATRAN ;
          I, J, K: INTEGER ;
      PROCEDURE TICH-MT (A,B: MATRAN: Var C: MATRAN;
      N: INTEGER) ;
          Begin
          {Nhân 2 ma trận vuông cấp N: C = A*B}
           FOR I:= 1 TO N DO
                Begin
                    C[I,J]:= 0 ;
                    FOR K:= 1 TO N DO
                    C[I,J]:= C[I,J] + A[I,K] *B[K, J];
                End ;
           End;
     BEGIN
     {Đọc vào giá trị của ma trận A}
      Writeln (’Nhập ma trận A:’)
      FOR I:= 1 TO N DO
           Begin
               Write (A[',I’,J,’] =’) ;
               Readln (A[I, J]) ;
           End; ,
    {Đọc vào giá trị của ma trận B}
    Writeln (’Nhập ma trận B:’) ;
     FOR J:=1TO N DO
     FOR J:= 1 TO N DO
          Begin
             Write (‘B[’,I’;’J,'] =’) ;
             Readln (B[I,J|) ;
          End ;
  TICH_MT (A, B, C, N) ;
  Writeln ('Tích của hai ma trận =') ;
  FOR I:= 1 TO N DO
       Begin
           FOR J:= 1 TO N DO Write (C[I,J1)
          Writein ;
       End ;
   END.
Mảng có thể dùng làm tham số cho chương trình con và mảng không bao giờ dùng làm kết quả của FUNCTION. Tuy nhiên cần khai báo kiểu của tham số trong vùng khai báo TYPE chứ không định nghĩa kiểu trực tiếp ngay trong phần khai tham số của CTC (xem thí dụ khai báo kiểu MT dưới đây).

■ Ví dụ 8:
Cộng hai ma trận C = A + B
PROGRAM CONG_MA_TRAN ;
     CONST
          N = 5 ;
TYPE MATRAN = ARRAY [1..N, 1..N] OF REAL ;
VAR
       X, Y, Z, MT ;
{………………………………………………………}
PROCEDURE CONG_MATRAN (A,B: MATRAN ; VAR C: MATRAN);
Var
       I, J: INTEGER ;
Begin
       FOR I:= 1 TO N DO
             FOR J:= 1 TO N DO
                 C[I,J]:= A[I,J] + B[I,J] ;
End ;
{………………………………………………………}
BEGIN

CONG_MATRAN(X, Y, X) ;

END.
Bạn đã không sử dụng Site, Bấm vào đây để duy trì trạng thái đăng nhập. Thời gian chờ: 60 giây