SỬ DỤNG HÀM TRONG C
CHƯƠNG 5 MẢNG, XÂU KÍ TỰ
5.1 KIỂU DỮ LIỆU MẢNG
Mảng là tập hợp các phần tử có cùng kiểu dữ liệu, được lưu trữ ở các vị trí kế tiếp nhau trong bộ nhớ chính. Ví dụ một mảng số nguyên gồm các phần tử có kiểu số nguyên, một mảng số thực bao gồm các phần tử có kiểu số thực.
Kích thước của mảng chính bằng số phần tử trong mảng. Khi khai báo số phần tử của mảng, máy tính sẽ cấp phát bộ nhớ bằng chính kích thước của mảng.
Mảng có thể là mảng một chiều hoặc mảng nhiều chiều.
5.1.1 Mảng một chiều
5.1.1.1 Các phần tử mảng và các chỉ mục
Mỗi phần tử của mảng được định danh bằng một chỉ mục hoặc chỉ số gán cho nó. Chiều của mảng được xác định bằng số chỉ số cần thiết để định danh duy nhất mỗi phần tử. Một chỉ số là một số nguyên dương được bao bằng dấu ngoặc vuông
[] đặt ngay sau tên mảng, không có khoảng trắng ở giữa. Một chỉ số chứa các giá trị nguyên bắt đầu bằng 0. Cụ thể hơn, một mảng A với 10 phần tử kiểu int sẽ được biểu diễn như sau:
A[0], A[1], A[2],...,A[9]
Chú ý rằng đối với ngôn ngữ C, chỉ số mảng luôn được bắt đầu từ 0. Như vậy,
trong mảng
N phần tử, phần tử cuối cùng có chỉ số là N-1. Phạm vi cho phép của các giá trị chỉ
số được gọi
là miền giới hạn của chỉ số mảng, giới hạn dưới và giới hạn trên. Một chỉ số
mảng hợp lệ
phải có một giá trị nguyên nằm trong niềm giới hạn. Nếu người dùng cố gắng truy xuất một
81
phần tử nằm ngoài dãy chỉ số hợp lệ (chẳng hạn A[10] trong ví dụ trên của mảng), trình biên dịch C sẽ không phát sinh ra lỗi. Tuy nhiên, có thể nó truy xuất một giá trị nào đó dẫn đến kết quả không đoán được. Cũng có nguy cơ viết chồng lên dữ liệu hoặc mã lệnh chương trình. Vì vậy, người lập trình phải đảm bảo rằng tất cả các chỉ số là nằm trong miền giới hạn hợp lệ.
5.1.1.2 Khai báo mảng
Một mảng có một vài đặc tính riêng biệt và phải được khai báo khi sử dụng chúng. Những đặc tính này bao gồm:
Lớp lưu trữ
Kiểu dữ liệu của các phần tử mảng.
Tên mảng - xác định vị trí phần tử đầu tiên của mảng.
Kích thước mảng - một hằng số có giá trị nguyên dương.
Một mảng được khai báo giống như cách khai báo một biến, ngoại trừ tên mảng được theo sau bởi một hoặc nhiều biểu thức, được đặt trong dấu ngoặc vuông [] xác định chiều dài (tổng số phần tử)của mảng. Cú pháp tổng quát khai báo một mảng như sau:
Lớp_lưu_trữ là một tùy chọn. Mặc định lớp automatic được dùng cho mảng khai báo bên
[Lớp_lưu_trữ] <Kiểu_dữ_liệu> Tên_mảng [Số phần tử ];
trong một hàm hoặc một khối lệnh, và lớp external được dùng cho mảng khai báo bên ngoài một hàm. Ví dụ:
int A[10]; //Khai báo mảng A có tối đa 10 phần tử
kiểu nguyên.
float B[100]; //Khai báo mảng B có tối đa 100 phần tử
kiểu số
thực.
Kích thước của mảng được tính bằng: số byte máy cấp phát cho kiểu dữ liệu * số phần tử của mảng. Chẳng hạn, mảng A đã khai báo ở trên có kích thước là 2*10
= 20 byte, mảng B có kích thước 4*100 = 400 byte,
Các qui tắc đặt tên mảng là giống với qui tắc đặt tên biến. Một tên mảng và một tên biến không được giống nhau, nó dẫn đến sự nhập nhằng. Nếu một sự khai báo như vậy xuất hiện trong chương trình, trình biên dịch sẽ hiển thị thông báo lỗi.
Một số qui tắc với mảng:
- Tất cả các phần tử của một mảng có cùng kiểu. Điều này có nghĩa là, nếu
một mảng
được khai báo kiểu int, nó không thể chứa các phần tử có kiểu khác.
- Kiểu dữ liệu của mảng có thể là các kiểu dữ liệu cơ bản như int, char,
float, double
hoặc các kiểu dữ liệu nâng cao như kiểu cấu trúc (được đề cập cụ thể trong chương 7).
- Mỗi phần tử của mảng có thể được sử dụng bất cứ nơi nào mà một biến được
cho phép
hay được yêu cầu.
- Một phần tử của mảng có thể được tham chiếu đến bằng cách sử dụng một
biến hoặc
một biểu thức nguyên. Sau đây là các tham chiếu hợp lệ:
A[i];
A[i] = A[i-1] + 5; A[2]
+= 3;
A[i/2+1];
82
5.1.1.3 Khởi tạo mảng
Việc khởi tạo mảng chính là thao tác gán giá trị cho từng phần tử mảng. Các
mảng không
được khởi tạo tự động, trừ khi mỗi phần tử mảng được gán một giá trị riêng lẻ.
Không nên
dùng các mảng trước khi có sự khởi tạo thích hợp. Điều này là bởi vì không gian
lưu trữ của
mảng không được khởi tạo tự động, do đó dễ gây ra kết quả không lường trước.
Mỗi khi các
phần tử của một mảng chưa khởi tạo được sử dụng trong các biểu thức toán học,
các giá trị đã
tồn tại sẵn trong ô nhớ sẽ được sử dụng, các giá trị này không đảm bảo rằng có
cùng kiểu như
khai báo của mảng, trừ khi các phần tử của mảng được khởi tạo một cách rõ ràng.
Điều này
đúng không chỉ cho các mảng mà còn cho các biến thông thường. Thực tế,
vòng lặp for
thường được sửdụng để khởi tạo mảng.
Chương trình sau đâysử dụng vòng lặp for để gán giá trị 0 cho tất cả các phần tử
của mảng A.
Ví dụ 5.1:
#include
<stdio.h
>main() {
int A[10], i;
for (i=0;
i<10; i++) A[i] = 0;
}
Các mảng cũng có thể được khởi tạo khi khai báo. Điều này được thực hiện bằng việc gán tên mảng với một danh sách các giá trị phân cách nhau bằng dấu phẩy (,) đặt trong cặp dấu ngoặc nhọn {}. Các giá trị trong cặp dấu ngoặc nhọn {} được gán cho các phần tử trong mảng theo đúng thứ tự xuất hiện.Ví dụ:
int A1[5] = {10, 20, 30, 40, 50};
float A2[4] = {0.0, -2.5, 13.75, 18.0}; char A3[5] = {‘A’, ‘P’, ‘P’, ‘L’, ‘E’};
int A4[100] = {11, 13, 15, 17}
Chú ý :
- Các giá trị khởi tạo của mảng phải là các hằng, không thể là biến hoặc các biểu thức.
- Nếu số lượng giá trị khởi tạo là ít hơn số phần tử mảng được khai báo. Các
phần tử còn
lại sẽ được khởi tạo giá trị 0.
Ví dụ, trong mảng A4 sau khi có sự khởi tạo như trên, bốn phần tử đầu tiên (từ 0 đến 3) tương ứng được khởi tạo là 11, 13, 115 và 17. Các phần tử còn lại có giá trị 0.
- Không thể chỉ khởi tạo các phần tử từ 1 đến 4, hoặc từ 2 đến 4, hay từ 2
đến 5 khi sự
khởi tạo được thực hiện tại thời điểm khai báo.
- Trong C không có khả năng lặp lại sự khởi tạo giá trị.
Trong trường hợp sự khởi tạo là tường minh, lớp extern hoặc static, các phần tử của mảng được đảm bảo khởi tạo là 0 (không giống lớp auto).
Không cần thiết khai báo kích thước của mảng đang được khởi tạo. Nếu kích thước của mảng được bỏ qua khi khai báo, trình biên dịch sẽ xác định kích thước của mảng bằng cách đếm các giá trị đang được khởi tạo. Ví dụ, sự khai báo mảng external sau đây sẽ chỉ định kích thước của mảng ary là 5 vì có 5 giá trị khởi tạo.
int ary[] = {1, 2, 3, 4, 5};
83
5.1.1.4 Nhập giá trị cho các phần tử mảng
Để nhập giá trị cho các phần tử của mảng có thể sử dụng cách nhập giá trị cho
từng phần tử
của mảng bằng phương pháp gán trực tiếp hoặc thông qua các vòng lặp
for, while,
do...while,...
Gán trực tiếp giá trị cho các phần
tử mảng
int A[3]; //Khai báo mảng
A[0] = 10; //Gán giá trị 10 cho phần tử
thứ nhất
A[1] = 12; //Gán giá trị 12 cho phần tử
thứ hai
A[2] = 30; //Gán giá trị 30 cho phần tử thứ ba
Nhập giá trị cho các phần tử thông qua
vòng lặp for
int A[20];
for (int
i=0;i<20;i++){
printf(“A[%d]
= ”,i);
scanf(“%d”,&a[
i]);
}
Chương trình sau đây sẽ khai báo một mảng A có tối đa 100 phần tử kiểu int và nhập giá trị các giá trị bất kỳ cho n phần tử đầu tiên trong mảng.
Ví dụ 5.2:
#include
<stdio.h
>
main() {
int A[100], i, n;
printf(" Input n = ");
scanf("%d", &n); for (i=0;
i<n; i++){
printf("A[%d] = ", i);
scanf("%d", &A[i]);
} }
Kết quả thực hiện của chương trình trên như sau:
Input n = 5
A[0] = 1
A [ 1 ]
= 2
A [ 2 ]
= 1 0
A [ 3 ]
= 1 5
A [ 4 ]
= 5
Trước tiên chương trình in ra dòng thông báo Input n = và chờ người dùng
nhập giá trị
cho n, sau đó tiếp tục yêu cầu nhập giá trị cho lần lượt các phần tử từ A[0] đến A[n-1]
của mảng.
5.1.1.5 Truy xuất đến các phần tử của mảng
Việc truy xuất đến các phần tử của mảng thường được thực hiện khi muốn
xem, hiển thị
hoặc sử dụng giá trị của chúng để tính toán, kiểm tra... Tương tự như trên, có thể
truy xuất các
phần tử mảng với các chỉ số cụ thể hoặc thông qua các vòng lặp for, while, do...while,...
Truy xuất phần tử mảng với các chỉ số cụ thể A[0] // Truy xuất phần tử đầu tiên
của mảng
A[5] // Truy xuất phần tử thứ 6 của mảng
Truy xuất các phần tử mảng thông qua vòng lặp for 84
for (int i=0;i<n;i++){
printf(“Phan tu thu %d = %d\n”,i+1, A[i]);
}
Chương trình sau đây sẽ khai báo một mảng A có tối đa 100 phần tử kiểu int
và nhập giá
trị các giá trị bất kỳ cho n phần tử đầu tiên trong mảng sau đó hiển thị các giá trị
đã nhập ra
màn hình.
Ví dụ 5.3:
#include
<stdio.h
>
main() {
int A[100], i, n;
printf(" Input n = ");
scanf("%d", &n); for (i=0;
i<n; i++){
printf("A[%d ] = ", i);
scanf("%d",
&A[i]); }
printf("\nDisplay the array:"); for (int i=0;i<n;i++){
printf("\nPhan tu thu %d = %d",i+1, A[i]);
} }
Kết quả thực hiện của chương trình trên như sau:
Input n = 5
A [ 0 ]
= 1 0
A [ 1 ]
=
5
A [ 2 ]
= 1 2
A [ 3 ]
= 1 5
A [ 4 ]
= 3 0
Display the array:
Phan tu thu 1 = 10 Phan tu thu 2 = 5 Phan tu thu 3 = 12 Phan tu thu 4 = 15
Phan tu thu 5 = 30 5.1.1.6 Quản lý mảng trong C
Một mảng được “đối xử” khác với một biến trong C. Thậm chí hai mảng có
cùng kiểu và
kích thước cũng không thể tương đương nhau. Hơn nữa, không thể gán một mảng
trực tiếp cho
một mảng khác. Thay vì thế, mỗi phần tử mảng phải được gán riêng lẻ tương
ứng với từng
phần tử của mảng khác. Các giá trị không thể được gán cho toàn bộ một mảng,
ngoại trừ tại
thời điểm khởi tạo. Tuy nhiên, từng phần tử không chỉ có thể được gán trị mà còn
có thể được
so sánh. Xét ví dụ sau, Ví dụ 5.4:
#include
<stdio.h
>
main() { int i;
int A1[5] = {0};
int A2[5] = {2, 3, 10, 12, 15};
85
printf("Before asign A2 to A1:\n"); for (i=0;i<5;i++)
printf("A1[%d]=%d,A2[%d]=
%d\n",i,A1[i],i,A2[i]); for (i=0; i<5;
i++)
A1[i] = A2[i];
printf("\nAfter asign A2
to A1:\n"); for
(i=0;i<5;i++)
printf("A1[%d]=%d,A2[%d]=%d\n",i,A1[i],i,A2[i]);
}
Kết quả thực hiện của chương trình trên như sau:
Before asign A2 to A1:
A1[0] = 0, A2[0] = 2 A1[1] = 0, A2[0] = 3 A1[2] = 0, A2[0] = 10 A1[3] = 0, A2[0] = 12 A1[4] = 0, A2[0] = 15 After asign A2 to A1:
A1[0] = 2, A2[0] = 2 A1[1] = 3, A2[0] = 3 A1[2] = 10, A2[0] = 10 A1[3] = 12, A2[0] = 12 A1[4] = 15, A2[0] = 15
Chương trình trên khai báo và khởi tạo giá trị cho hai mảng kiểu nguyên A1 và A2. Các phần tử của mảng A1 ban đầu được khởi tạo bằng 0, các phần tử của A2 0. Sau đó sử dụng vòng lặp for để các phấn tử tương ứng của mảng A2 cho A1.
Trong trường hợp không sử dụng vòng lặp for, có thể sử dụng các lệnh gán riêng lẻ như sau: A1[0] = A2[0]
A1[1] = A2[1]
A1[4] = A2[4]
Trong thực tế, cấu trúc for là cách lý tưởng để thao tác các mảng.
5.1.1.7 Truyền mảng vào hàm
Trong C, khi một mảng được truyền vào hàm như một tham số, thì chỉ có địa chỉ của mảng được truyền vào. Tên mảng không kèm theo chỉ số là địa chỉ của mảng. Đoạn mã dưới đây mô tả cách truyền địa chỉ của mảng A cho hàm func():
void main(){
int A[10];
func(A);
}
Nếu tham số của hàm là một mảng một chiều thì tham số đó có thể được khai báo theo một
trong các cách sau:
func (int ary [10]) /* Xác định trước số phần tử mảng*/
{ }
86
Hoặc:
func (int ary []) /*Không xác định trước số phần
tử mảng*/
{ }
Cả hai khai báo ở trên đều cho cùng kết quả. Kiểu thứ nhất sử dụng cách khai báo mảng chuẩn, chỉ rõ ra kích thước của mảng. Kiểu thứ hai, chỉ ra rằng tham số là một mảng kiểu int có kích thước bất kỳ. Xét ví dụ sau:
Ví dụ 5.5:
#include <stdio.h>
void InputArray(int A[], int n);
int FindMax(int A[], int n);
int main(){
int i, n, A[100];
printf("Input n = ");
scanf("%d", &n);
InputArray(A, n);
printf("Display inputed array: "); for (int i=0;
i<n; i++)
printf("%d ", A[i]);
printf("\nMax = %d", FindMax(A, n));
}void InputArray(int A[], int n){
for (int i=0; i<n; i++){
printf("A[%d] = ", i); scanf("%d", &A[i]);
} }
int FindMax(int A[], int n){
int max = A[0];
for (int i=1;
i<n; i++) if (max<A[i])
max = A[i];
return max;
}
Kết quả thực hiện của chương trình như sau:
Input n = 5
A[0]=3
A [ 1 ]
= 2
A [ 2 ]
= 1
A [ 3 ]
= 7
A [ 4 ]
= 5
Display inputed array:
3 2 1 7 5 Max = 7
Chương trình trên khai báo một mảng số nguyên A có tối đa 100 phần tử và số
nguyên n
(số phần tử người dùng muốn nhập). Sau khi giá trị n đã được nhập, mảng A và
n sẽ được
truyền vào hàm InputArray(), hàm này sẽ nhập vào n phần tử mảng từ bàn
phím. Sau đó
chúng sẽ được truyền tới hàm FindMax(). Hàm này sẽ tìm kiếm và trả về giá trị
lớn nhất trong
mảng.
87
5.1.2 Mảng đa chiều 5.1.2.1 Khái niệm
Các mảng đa chiều giúp dễ dàng trình bày các đối tượng đa chiều, chẳng hạn một đồ thị với các dòng và cột hay tọa độ màn hình của máy tính. Các mảng đa chiều được khai báo giống như các mảng một chiều, ngoại trừ có thêm một cặp dấu ngoặc vuông [] trong trường hợp mảng hai chiều. Một mảng 3 chiều sẽ cần 3 cặp dấu ngoặc vuông,... Một cách tổng quát, một mảng n chiều có thể được biểu diễn như sau:
[ Lớp_lưu_trữ ] < Kiểu dữ liệu> Tên_mảng [D1] [D2] … [Dn];
Trong đó, D1 là tổng số phần tử của chiều thứ nhất, D2 là tổng số phần tử của chiều thứ 2,…, Dn là tổng số phần tử của chiều thứ n.
Dạng đơn giản nhất và thường được sử dụng nhất của các mảng đa chiều là mảng hai chiều. Mảng hai chiều hay còn gọi là ma trận. Mỗi một phần tử trong mảng hai chiều được gán hai chỉ số đó là chỉ số hàng và chỉ số cột.
5.1.2.1 Khai báo mảng hai chiều
Cú pháp tổng quát khai báo mảng haichiều được thể hiện như sau:
[Lớp_lưu_trữ] <Kiểu dữ liệu> Tên mảng [số hàng] [sốcột];
Một mảng hai chiều kiểu nguyên với hàng, 5 cột được khai báo như sau:
int A[3][5];
Mảng này sẽ chứa 35 = 15 phần tử, được biểu diễn như sau:
A[0][0] A[0][1] A[0][2] A[0][3] A[0][4]
A[1][0] A[1][1] A[1][2] A[1][3] A[1][4]
A[2][0] A[2][1] A[2][2] A[2][3] A[2][4]
5.1.2.1 Khởi tạo mảng hai chiều
Khai báo mảng hai chiều có thể kết hợp với việc gán các giá trị khởi tạo.
Việc khởi tạo mảng haichiều được thực hiện theo một trong những cách thức sau đây.
Phương pháp 1: Khởi tạo như mảng mộtchiều, ví dụ:
int A[3][4] ={1,3,5,7,2,4,6,8,10,20,30,40};
Với khai báo này, bốn giá trị đầu tiên sẽ được gán cho hàng thứ nhất, bốn giá
trị tiếp theo
được gán cho hàng thứ 2 và bốn giá trị cuối cùng được gán cho hàng thứ 3. Kết
quả cụ thể như
sau:
A[0][0]=1, A[0][1]=3, A[0][2]=5, A[0][3]=7 A[1][0]=2, A[1][1]=4, A[1][2]=6, A[1][3]=8 A[2][0]=10, A[2][1]=20, A[2][2]=30, A[2][3]=40
Phương pháp 2: Các giá trị khởi tạo trên mỗi hàng được nhóm lại lại trong các dấu ngoặc nhọn {}, ví dụ:
int ary[3][4] = {{1,3,5,7},{2,4,6,8},{10,20,30,40}};
Lệnh khai báo này cũng cho kết quả như khai báo trên.
Tương tự như mảng mộtchiều, nếu số lượng giá trị khởi tạo là ít hơn số phần tử
mảng được khai báo, các phần tử còn lại sẽ được khởi tạo giá trị 0.
Các chương trình sau đây sẽ khai báo và gán giá trị cho một mảng haichiều A, sau đó hiển thị giá trị của các phần tử mảng ra màn hình.
88
Ví dụ 5.6:
#include
<stdio.h
>main() {
int i, j;
int A[3][4] ={{1,3,5},{2,4,6}, {10,20,30}}; printf("Display inputed array:\n ");
for (i=0; i<3; i++){
for (j=0; j<4; j++)
printf("A[%d][%d] = %d\t", i, j, A[i][j]); printf("\n");
} }
Kết quả thực hiện của chương trình trên như sau:
A[0][0] = 1, A[0][1] = 3, A[0][2] = 5, A[0][3] = 0 A[1][0] = 2, A[1][1] = 4, A[1][2] = 6, A[1][3] = 0 A[2][0] = 10, A[2][1] = 20, A[2][2] = 30, A[2][3] = 0 Vì mỗi cặp dấu ngoặc nhọn {} trong lệnh khai báo mảng A chỉ chứa 3 giá trị nên 3 phần tử đầu tiên của mỗi hàng sẽ được gán và phần tử cuối cùng trong mỗi hàng có giá trị bằng 0.
5.1.1.4 Nhập giá trị cho các phần tử mảng
Tương tự như mảng 1 chiều, để nhập giá trị cho các phần tử của mảng 2 chiều có thể sử dụng cách nhập giá trị cho từng phần tử của mảng bằng phương pháp gán trực tiếp hoặc thông qua các vòng lặp for, while, do...while,...
Gán trực tiếp giá trị cho các phần tử mảng int A[2][3]; /*Khai báo mảng*/
A[0][0] = 1; A[0][1] = 2; A[0][2] = 3;
A[1][0] = 4; A[0][1] = 5;
A[0][2] = 6;
A[0][0] = 7; A[0][1] = 8;
A[0][2] = 9;
Nhập giá trị cho các phần tử thông qua
vòng lặp for
int A[2][3];
int i,j;
for (i=0;i<2;i++) for (j=0; j<3; j++){
printf(“A[%d][%d] = ”,i,j);
scanf(“%d”,&a[i][j]);
}
Ví dụ sau đây sẽ khai báo một mảng haichiều các số nguyên. Mảng có kích
thước tối đa 50
hàng và 100 cột. Chương trình nhận vào 2 giá trị m, n tương ứng với số hàng và
số cột thực sự
mà người dùng thao tác, sau đó cho phép người dùng nhập vào mn phần tử từ bàn phím.
Ví dụ 5.7:
#include
<stdio.h
>
main(){
int A[20]
[30];
int i, j, m, n;
//Nhậ p m,n
printf("Input m, n: ");
scanf("%d%d",
&m, &n);
//Nhập giá trị cho các phần tử mảng for (i=0;
i<m; i++)
89
for (j=0; j<n; j++){
printf("A[%d][%d]
= ",i,j);
scanf("%d",&A[i]
[j]);
} }
Kết quả thực hiện của chương trình trên như sau:
Input m, n:3 3
A[0][0] = 1 A[0][1] = 2
A[0][2] = 3 A[1][0] = 4
A[1][1] = 5
A[1][2] = 6
A[2][0] = 7
A[2][1] = 8
A[2][2] = 9
Việc nhập giá trị cho các phần tử của mảng haichiều ở trên được thực thông qua haivòng lặp for lồng nhau. Trong đó, vòng lặp ngoài được sử dụng để duyệt theo chỉ số hàng, vòng lặp trong duyệt theo chỉ số cột.
5.1.1.2 Truy nhập các phần tử của mảng
Tương tự như mảng mộtchiều, có thể truy xuất các phần tử mảng với các chỉ số cụ thể hoặc thông qua các vòng lặp for, while, do...while,...
Truy xuất phần tử mảng với các chỉ số cụ thể
A[0][0]; //Truy xuất phần tử đầu tiên(hàng 0, cột 0) A[1][3]; //Truy xuất phần tử ở hàng 2 và cột 4
A[m-1][n-1]; //Truy xuất phần tử cuối cùng
Truy xuất các phần tử mảng thông qua vòng lặp for for (int i=0;i<m;i++){
for (j=0; j<n; j++) {
printf(“Phan tu thu %d = %d\n”,i+1, A[i]);
} }
Do bên trong vòng lặp ngoài (fori) chỉ chứa một lệnh lặp (forj) nên có thể bỏ cặp dấu ngoặc xoắn {} ngoài cùng.
Chương trình sau đây sẽ mở rộng chương trình ở ví dụ 5.7 bằng cách bổ sung thêm đoạn mã để hiển thị giá trị của các phần tử đã nhập ra màn hình.
Ví dụ 5.8:
#include
<stdio.h
>
main(){
int A[20]
[30];
int