Dữ liệu mảng và danh sách
Mảng là gì?
Mảng là một danh sách có thứ tự các dữ liệu vô hớng. Mỗi phần tử của mảng đều
là một biến vô hớng tách biệt với một giá trị vô hớng độc lập. Các giá trị này là đợc
sắp thứ tự - tức là chúng có một trình tự đặc biệt từ phần tử thấp nhất đến cao nhất.
Mảng có thể có bất kì số phần tử nào. Mảng nhỏ nhất không có phần tử nào, trong
khi mảng lớn nhất thì có thể lấp kín toàn bộ bộ nhớ có sẵn. Một lần nữa, điều này lại
đợc giữ hợp với triết lí của Perl về không có giới hạn không cần thiết nào.
Biểu diễn hằng kí hiệu
Một hằng kí hiệu mảng (cách thức bạn biểu diễn giá trị của một mảng bên trong
chơng trình mình) là một danh sách các giá trị tách nhau bằng dấu phẩy và đợc bao
trong dấu ngoặc tròn. Những giá trị này tạo nên các phần tử của danh sách. Chẳng
hạn:
(1,2,3) # mảng gồm ba giá trị 1, 2 và 3
(fred, 4.5) # hai giá trị, fred và 4.5
Các phần tử của mảng không nhất thiết là hằng - chúng có thể là biểu thức mà sẽ
đợc tính mới lại mỗi lần hằng đợc sử dụng. Chẳng hạn:
($a, 17) # hai giá trị: giá trị hiện tại của $a, và 17
($b+$c,$d+$e) # hai giá trị
Mảng rỗng (mảng không có phần tử nào) đwjc biểu diễn bằng một cặp dấu ngoặc
rỗng:
() # mảng rỗng (không phần tử)
Một phần tử của mảng có thể bao gồm toán tử cấu tử mảng, đợc chỉ ra bởi hai
giá trị vô hớng tách nhau bởi hai dấu chấm liên tiếp. Toán tử này tạo ra một danh sách
các giá trị bắt đầu tại giá trị vô hớng bên trái kéo cho tới gía trị vô hớng bên phải, mỗi
lần tăng lên một. Chẳng hạn:
(1..5) # giống nh (1, 2, ,3 ,4, 5)
(1.2..5.2) # giống nh (1.2, 2.2, 3.2, 4.2, 5.2)
(2..6,10,12) # giống nh (2,3,4,5,6,10,12)
($a..$b) # phạm vi đợc xác định bởi giá trị hiện tại của $a và $b
Nếu giá trị vô hớng bên phải bé hơn vô hớng bên trái thì sẽ tạo ra danh sách rỗng
ớng hay mảng
*
. Chẳng hạn:
@fred = (1,2,3); # mảng fred nhận ba phần tử hằng kí hiệu
@barney = @fred; # bây giờ đợc sao sang @barney
Nếu một giá trị vô hớng đợc gán vào trong một biến mảng thì giá trị vô hớng trở
*
*
Điều này áp dụng cho lvalue vô hớng hay mảng cũng nh các biến đơn
thành phần tử duy nhất của mảng:
@huh = 1; # 1 đợc đặt cho danh sách (1) một cách tự động
Tên biến mảng có thể xuất hiện trong danh sách hằng kí hiệu mảng. Khi giá trị
của danh sách đợc tính thì Perl thay thế tên biến mảng bằng giá trị hiện tại của mảng
đó, giống vậy:
@fred = (một, hai);
@barney = (4,5,@fred, 6, 7); @barney trở thành
(4,5,một,hai,6,7)
@barney = (8, @barney); # đặt 8 vào trớc @barney
@barney = (@barney, cuối); # và cuối là ở cuối
# @barney bây giờ là (8,4,5,một,hai,6,7,cuối)
Lu ý rằng các phần tử mảng đợc thêm vào đều ở cùng mức nh phần còn lại của
hằng kí hiệu - một danh sách không thể chứa một danh sách khác nh một phần tử
*
.
Nếu một mảng hằng kí hiệu chỉ chứa các tham khảo biến (không phải là biểu
thức) thì mảng hằng kí hiệu ấy cũng có thể đợc xử lí nh một biến. Nói cách khác, một
mảng hằng kí hiệu nh thế có thể đợc dùng ở vế bên trái của phép gán. Mỗi biến vô h-
ớng trong mảng kí hiệu nhận một giá trị tơng ứng từ danh sách ở vế phải của phép
gán. Chẳng hạn:
($a, $b, $c) = (1, 2, 3); # đặt 1 cho $a, 2 cho $b, 3 cho $c
Giá trị của phép gán mảng là chính bản thân giá trị mảng, và có thể đợc xếp tầng
nh bạn có thể làm với các phép gán vô hớng. Chẳng hạn:
@fred = (@barney = (2,3,4)); # @fred và @barney nhận (2,3,4)
@fred = @barney = (2,3,4); # cùng điều ấy
Thâm nhập phần tử
Cho tới nay, chúng ta vẫn xử lí mảng nh một tổng thể, thêm vào và bỏ bớt các giá
trị bằng việc thực hiện gán mảng. Nhiều chơng trình có ích đã đợc xây dựng dùng
mảng mà thậm chí chẳng thâm nhập vào phần tử mảng nào. Tuy nhiên, Perl cung cấp
toán tử chỉ số truyền thống để tham khảo tới một phần tử mảng theo chỉ số.
Với toán tử chỉ số mảng, các phần tử mảng đều đợc đánh số bằng việc dùng số
nguyên tuần tự, bắt đầu từ không
*
và tăng lên một cho mỗi phần tử. Phần tử đầu tiên
của mảng @fred mà đợc thâm nhập tới là $fred[0]. Chú ý rằng @ trên tên mảng trở
thành $ trên tham khảo phần tử. Đó là vì việc tham khảo tới một phần tử của mảng
xác định ra một biến vô hớng (một phần của mảng), mà có thể hoặc đợc gán cho,
hoặc có giá trị hiện tại của nó đợc dùng trong một biểu thức, kiểu nh:
@fred = (7,8,9);
$b = $fred[0]; # đặt 7 vào $b (phần tử đầu tiên của @fred)
$fred[0] = 5; # bây giờ @fred = (5,8,9)
Cũng có thể thâm nhập tới các phần tử khác dễ tơng tự, nh trong:
$c = $fred[1]; $ đặt 8 cho $c
$fred[2]++; # tăng phần tử thứ ba của @fred
$fred[1] += 4; # cộng 4 vào phần tử thứ hai
($fred[0], $fred[1]) = ($fred[1], $fred[0]); # tráo đổi hai phần tử đầu
Việc thâm nhập vào một danh sách các phần tử từ cùng mảng (nh trong thí dụ
*
*
Cũng có thể thay đổi giá trị chỉ số của phần tử đầ utiên thành một số nào đó khác (nh một) bằng việc đặt giá trị cho
biến $[. Tuy nhiên, làm nh vậy có ảnh hởng toàn cục, mà có thể gây lẫn lộn ngời sẽ bảo trì chơng trình của bạn, và có
@backfred = @fred[@barney];
# giống nh @fred[2,1,0], hay ($fred[2],$fred[1],$fred[0]),
# hay (9,8,7)
Nếu bạn thâm nhập vào một phần tử mảng bên ngoài hai đầu của mảng hiện tại
(tức là một chỉ số bé hơn không hay lớn hơn chỉ số của phần tử cuối cùng), thì giá trị
undef sẽ đợc cho lại mà không có lời cảnh báo. Chẳng hạn:
@fred = (1,2,3);
$barney = $fred[7]; # $barney bây giờ là undef