
275
Chƣơng 5
MẢNG VÀ CON TRỎ
Ngoài các kiểu dữ liệu cơ bản (số nguyên, số thực, ký tự), trong ngôn
ngữ lập trình C cho phép ngƣời lập trình viên có thể tạo ra các kiểu dữ
liệu mới. Trong Chƣơng 5, các vấn đề sau đây sẽ đƣợc đề cập đến:
- Mảng một chiều và mảng hai chiều: Khai báo, cách thức truy cập
các phần tử trong mảng, một số dạng bài tập với mảng một chiều và mảng
hai chiều.
- Con trỏ: Định nghĩa, khai báo con trỏ, các phép toán với biến con trỏ,
mối quan hệ giữa con trỏ và mảng, sử dụng con trỏ cấp phát bộ nhớ động.
- Chuỗi ký tự: Khai báo, các phép toán trên chuỗi, một số dạng bài
tập vận dụng xử lý đối với chuỗi.
5.1. MẢNG
5.1.1. Mảng một chiều
Mảng một chiều là tập hợp các thành phần có cấu trúc (thƣờng đƣợc
gọi là các phần tử mảng) có thể đƣợc truy cập riêng lẻ bằng cách chỉ định
vị trí của một thành phần với giá trị chỉ số duy nhất. Mảng phải đƣợc khai
báo trƣớc khi chúng có thể đƣợc sử dụng trong chƣơng trình.
5.1.1.1. Khai báo mảng
Cú pháp:
data_Type arrayName [ arraySize ];
Trong đó:
data_Type: là kiểu giá trị của các phần tử mảng, có thể là kiểu dữ
liệu cơ bản nhƣ kiểu số nguyên, số thực, ký tự, chuỗi, v.v. hoặc cũng có
thể là kiểu dữ liệu có cấu trúc nhƣ kiểu bản ghi, v.v.
arrayName: là tên đƣợc đặt cho mảng, cách thức đặt tên biến mảng
giống nhƣ định danh.
arraySize: kích thƣớc của mảng, luôn đƣợc đặt trong cặp dấu [].
Ví dụ 5.1
Cho khai báo sau đây:
int a[5];

276
Khai báo một mảng có tên là a, số lƣợng phần tử của mảng là 5, kiểu
dữ liệu của mỗi phần tử trong mảng a là số nguyên. Chỉ số các phần tử
của mảng đƣợc đánh từ 0 đến 4. Hình ảnh minh họa của mảng một chiều:
a[0]
a[1]
a[2]
a[3]
a[4]
Lƣu ý:
Có thể khai báo và khởi tạo giá trị mảng ban đầu. Khởi tạo mảng rất
đơn giản trong lập trình C. Các giá trị khởi tạo đƣợc đặt trong dấu ngoặc
nhọn trong khai báo và đƣợc đặt sau dấu bằng sau tên mảng. Dƣới đây là
một ví dụ khai báo và khởi tạo một mảng gồm năm phần tử kiểu int.
Mảng cũng có thể đƣợc khởi tạo sau khi khai báo.
Ví dụ 5.2
int a[5] = {13, -6, 9, 45, 7};
Không cần thiết phải xác định kích thƣớc của mảng trong quá trình
khởi tạo, nhƣ ví dụ 5.3 sau đây:
Ví dụ 5.3
int a[] = {13, -6, 9, 45, 7};
Trong trƣờng hợp này, trình biên dịch xác định kích thƣớc của mảng
bằng cách tính số lƣợng phần tử của mảng:
a[0]
a[1]
a[2]
a[3]
a[4]
13
-6
9
45
7
Điều này rất hữu ích vì kích thƣớc của mảng có thể đƣợc kiểm soát
bằng cách thêm hoặc xóa các phần tử khởi tạo khỏi định nghĩa mà không
cần điều chỉnh kích thƣớc.
Nếu kích thƣớc mảng đƣợc xác định trƣớc, tức đƣợc cấp phát bộ nhớ
theo số phần tử đã khai báo, nhƣng chỉ một số phần tử trong mảng đƣợc
khởi tạo, khi đó các phần tử còn lại sẽ chứa giá trị 0. Với cách thức khai
báo nhƣ vậy rất thích hợp trong trƣờng hợp phải xử lý với mảng lớn.
Ví dụ 5.4
Cho khai báo: int a[2000] = {13, 9};
Với khai báo trên, a[0] = 13, a[1] = 9, a[2] = 0,…, a[1999] = 0.
5.1.1.2. Truy cập các phần tử của mảng
Trong C, mảng đƣợc truy cập và xử lý giống nhƣ các biến.
Cú pháp:

277
arrayName(index);
Trong đó:
arrayName: Tên biến mảng
index: Chỉ số phần tử truy cập;
Ví dụ 5.5
Câu lệnh chèn giá trị vào phần tử thứ 3 trong mảng a:
scanf(“%d”, &a[2]);
Câu lệnh in giá trị của phần tử tứ 3 trong mảng a:
printf(“%d”, a[2]);
Trong C, mảng có truy cập và cập nhật bằng chỉ số mảng. Nếu mảng
có n phần tử, thì chỉ số của mảng đƣợc gán từ 0 đến n - 1. Không giống
nhƣ ngôn ngữ Java, khi chỉ số mảng nằm ngoài phạm vi từ 0,…, n - 1,
đƣợc xử lý ngoại lệ trong cặp lệnh try…catch, mảng trong C có thể
không hiển thị bất kỳ một cảnh báo nào nếu chỉ số mảng ngoài giới hạn
đƣợc truy cập. Thay vào đó, trình biên dịch có thể truy cập các phần tử
ngoài phạm vi, do đó dẫn đến các lỗi nghiêm trọng về thời gian thực hiện
chƣơng trình.
Để giảm bớt các “rủi ro” các vấn đề liên quan đến chỉ số của mảng,
biểu thức sizeof() thƣờng đƣợc sử dụng để xử lý vòng lặp trong mảng.
Chúng ta có thể sử dụng một marco sử dụng biểu thức sizeof() để tìm số
lƣợng phần tử của mảng, marco này có các tên khác nhau nhƣ
“lengthof()”, “MY_ARRAY_SIZE()”, hoặc “NUM_ELEM()”,
“SIZEOF_STATIC_ARRAY()” , v.v.
Ví dụ 5.6
Cho đoạn chƣơng trình sau đây:
1
#include <stdio.h>
2
int main()
3
{
4
int i;
5
int a[] = {13, -6, 9, 45, 7};
6
for (i = 0; i < sizeof(a)/sizeof(int); i++)
7
{
8
printf("%d\t", a[i]);

278
9
}
10
return 0;
11
}
Kết quả chƣơng trình:
13 -6 9 45 7
Lƣu ý trong ví dụ trên, kích thƣớc của mảng không đƣợc chỉ định rõ
ràng. Trình biên dịch biết kích thƣớc của nó là 5 vì 5 giá trị trong danh
sách khởi tạo. Thêm một giá trị bổ sung vào danh sách sẽ khiến nó có
kích thƣớc thành 6 và do biểu thức sizeof trong vòng lặp for, mã sẽ tự
động điều chỉnh theo thay đổi này. Thực hành lập trình tốt là khai báo một
kích thƣớc thay đổi và lƣu trữ số lƣợng phần tử trong mảng trong đó.
size = sizeof (tên_mảng) / sizeof (kiểu_dữ_liệu_mảng)
5.1.1.3. Các dạng bài tập mảng một chiều
Dạng 1: Nhập và hiển thị mảng một chiều
a. Nhập mảng
Cách 1:
Nhập từng phần tử của mảng.
Để nhập các phần tử của mảng, ta thực hiện nhƣ sau:
- Nhập từng phần tử của mảng sử dụng một vòng lặp
- Xây dựng một hàm nhap() có kiểu void, không trả về giá trị, truyền
vào hai tham số là tên biến mảng và số lƣợng phần tử của mảng.
Cách 2: Sinh ngẫu nhiên các phần tử của mảng, sử dụng hàm rand()
để sinh ra các giá trị ngẫu nhiên.
Cú pháp hàm rand():
int rand(void)
Hàm rand() không nhận tham số vào, trả về một giá trị ngẫu nhiên
trong phạm vi từ 0 đến RAND_MAX. Trong đó, RAND_MAX là một
hằng số có giá trị mặc định (đƣợc định nghĩa trong thƣ viện “stdlib.h”,
thông thƣờng RAND_MAX = 32767)
b. Hiển thị mảng
Để hiển thị các phần tử của mảng, ta thực hiện nhƣ sau:
- Sử dụng một vòng lặp để hiển thị các phần tử của mảng.
- Xây dựng một hàm hienthi() có kiểu void, truyền vào hai tham số là
tên biến mảng và số lƣợng phần tử của mảng.

279
Ví dụ 5.7
Viết chƣơng trình nhập vào một mảng gồm n số nguyên (n là số phần
tử của mảng, đƣợc nhập từ bàn phím) và hiển thị các phần tử ra màn hình,
mỗi phần tử cách nhau độ dài phím tab.
Phác thảo lời giải
Xây dựng 2 hàm:
- Hàm nhap(): Sử dụng một vòng lặp for nhập từng phần tử của mảng.
- Hàm hienthi(): Sử dụng một vòng lặp for, hiển thị các phần tử của mảng.
Chƣơng trình:
1
#include <stdio.h>
2
void nhap(int a[], int n) {
3
for (int i = 0; i < n; i++) {
4
printf("Gia tri phan tu a[%d]=", i);
5
scanf("%d", &a[i]); }
6
}
7
void hienthi(int a[], int n)
8
{
9
printf("Hien thi cac phan tu cua mang :\n");
10
for(int i=0; i < n; i++)
11
printf("%4d", a[i]);
12
}
13
int main(){
14
int a[1000];
15
int n;
16
printf("Nhap so phan tu cua mang =");
17
scanf("%d", &n);
18
nhap(a, n);
19
hienthi(a,n);
20
return 0;
21
}
Kết quả chƣơng trình:
Nhap so phan tu cua mang = 3
Gia tri phan tu a[0] = 54

