Bài giảng Ngôn ngữ lập trình - Bài 2: Các cấu trúc điều khiển, mảng và con trỏ - Lê Nguyễn Tuấn Thành
Tóm tắt Bài giảng Ngôn ngữ lập trình - Bài 2: Các cấu trúc điều khiển, mảng và con trỏ - Lê Nguyễn Tuấn Thành: ...hao tác danh sách như một thực thể (entity) 29 MẢNG KHAI BÁO  Khai báo mảng là cấp phát một dải vùng nhớ (allocate memory)  Cấu trúc: Kiểu Tên_Mảng[Kích_Thước]  Ví dụ: int score[5];  Khai báo một mảng gồm 5 số nguyên tên là “score”  Giống như khai báo 5 biến: int score[0], score[1], sc...uyên với đối đa 100 hàng và 100 cột, xét xem mảng có đối xứng qua đường chéo chính hay không ? 46 4. CON TRỎ 4. CON TRỎ (POINTER)  Con trỏ  Biến con trỏ (pointer variables)  Quản lý bộ nhớ  Mảng động (dynamic arrays)  Tạo và sử dụng mảng động  Phép tính với con trỏ (pointer arithmet...ể dẫn đến hết bộ nhớ freestore  Thao tác cấp phát động (với toán tử new) có thể không thực hiện được nếu freestore bị đầy 61 KIỂM TRA KẾT QUẢ CẤP PHÁT BỘ NHỚ (1/2)  Với những trình biên dịch cũ, thực hiện 2 bước 1. Kiểm tra liệu giá trị null có được trả về sau khi gọi new hay không int *p...
NGÔN NGỮ LẬP TRÌNH
Bài 2:
Các cấu trúc điều khiển, 
mảng và con trỏ
Giảng viên: Lê Nguyễn Tuấn Thành
Email: thanhlnt@tlu.edu.vn
Bộ Môn Công Nghệ Phần Mềm – Khoa CNTT
Trường Đại Học Thủy Lợi
NỘI DUNG
1. Cấu trúc rẽ nhánh
2. Cấu trúc lặp
3. Mảng (Array)
4. Con trỏ (Pointer)
2
Bài giảng có sử dụng hình vẽ trong cuốn sách “Practical Debugging in C++, 
A. Ford and T. Teorey, Prentice Hall, 2002”
1. CẤU TRÚC RẼ NHÁNH
1.1. CẤU TRÚC RẼ NHÁNH VỚI IF-ELSE
 Mục đích
 Diễn đạt sự lựa chọn một trong nhiều nhánh, phụ
thuộc vào giá trị của câu điều kiện
 Cú pháp:
if ()
else
 Ví dụ:
if (hrs > 40)
grossPay = rate*40 + 1.5*rate*(hrs-40);
else
grossPay = rate*hrs;
4
CÂU LỆNH PHỨC HỢP
 Mỗi nhánh trong if-else ở slide trước chỉ có một
câu lệnh
 Để ghép nhiều câu lệnh trong một nhánh, sử dụng
{ }. Tập lệnh khi đó được gọi là một khối (block)
 Ví dụ:
if (myScore > yourScore)
{
cout << "I win!\n";
wager = wager + 100;
}
else
{
cout << "I wish these were golf scores.\n";
wager = 0;
}
5
MỘT VÀI LƯU Ý
 Toán tử “=” khác toán tử “==” như thế nào?
 “=” dùng để gán giá trị cho các biến
 “==” dùng để so sánh hai biểu thức
 Mệnh đề else có bắt buộc không?
 Ví dụ:
if (sales >= minimum)
salary = salary + bonus;
cout << "Salary = %" << salary;
6
CÂU LỆNH LỒNG NHAU (NESTED)
 Chúng ta có thể lồng một cặp if-else trong một
nhánh của cặp if-else khác
 Ví dụ:
if (speed > 55)
if (speed > 80)
cout << "You’re really speeding!";
else
cout << "You’re speeding.";
7
ĐA RẼ NHÁNH (IF - ELSE IF - ELSE)
8
BÀI TẬP VỚI CẤU TRÚC RẼ NHÁNH IF-ELSE
 Viết một chương trình C++ để nhắc người dùng nhập 3
số nguyên và tìm giá trị lớn nhất.
Câu hỏi:
Nếu có quá nhiều nhánh rẽ thì ngoài sử dụng if-
else, C++ còn cung cấp cách nào nữa không?
9
1.2. RẼ NHÁNH VỚI LỆNH WITCH (1/2)
10
RẼ NHÁNH VỚI LỆNH WITCH (2/2)
11
LỆNH SWITCH: CÂU HỎI
switch (aChar)
{
case "A":
case "a":
cout << "Excellent: you got an "A"!\n";
break;
case "B":
case "b":
cout << "Good: you got a "B"!\n";
break;
}
Nếu giá trị của aChar là “A” hoặc “B” thì kết quả in
ra là gì ? 12
TOÁN TỬ ĐIỀU KIỆN
(CONDITIONAL/TERNARY OPERATOR)
 Thay thế cho mệnh đề if-else đơn giản với hai toán tử
“?” và “:”
 Cấu trúc: 
if (condition)
if_true; 
else
if_false;
Có thể thay bằng một lệnh 
(condition) ? (if_true) : (if_false) 
Bài tập: viết hàm trả lại số lớn nhất trong hai số
 #define MAX(a, b) ((a > b) ? a : b)
 #define MIN(a, b) ((a < b) ? a : b)
 Giá trị của a trong câu lệnh sau (với x > 0) a = x ? : y; 13
2. CẤU TRÚC LẶP
2. CẤU TRÚC LẶP (LOOP)
Các cấu trúc lặp trong C++
1. While
2. do-while
3. for
15
CẤU TRÚC LẶP VỚI WHILE
16
int count = 0; // Initialization
while (++count < 3) // Loop Condition
{
cout << "Hi "; // Loop Body 
}
Chuỗi “Hi” sẽ được in ra màn hình bao nhiêu lần?
CẤU TRÚC LẶP VỚI DO-WHILE (1/2)
17
CẤU TRÚC LẶP VỚI DO-WHILE (2/2)
int count = 0; // Initialization
do 
{
cout << "Hi "; // Loop Body
} while (++count < 3); // Loop Condition
Chuỗi “Hi” sẽ được in ra màn hình bao nhiêu lần?
18
SO SÁNH WHILE VÀ DO-WHILE
 Khá giống nhau, nhưng một khác biệt quan trọng
 while: kiểm tra điều kiện logic TRƯỚC KHI thực thi
lệnh bên trong
 do-while: kiểm tra điều kiện logic SAU KHI đã thực
thi lệnh bên trong
19
CẤU TRÚC LẶP VỚI FOR
 Cú pháp
for (Init_Action; Bool_Expression; Update_Action)
Body_Statement
 Ví dụ:
for (count=0; count<3; count++) 
{
cout << "Hi "; // Loop Body
}
 Chuỗi “Hi” sẽ được in ra màn hình bao nhiêu lần?
 Điều gì xảy ra với câu lệnh sau: 
 for ( ; ;) { cout << “Hi”; }
20
MỘT VÀI CHÚ Ý VỚI CẤU TRÚC LẶP (1/2)
 Biểu thức điều kiện của vòng lặp có thể là BẤT KỲ 
biểu thức logic nào
 Ví dụ:
while (count<3 && done!=0)
{
// Do something
}
-----
for (index=0; index<10 && entry!=99)
{
// Do something
}
21
MỘT VÀI CHÚ Ý VỚI CẤU TRÚC LẶP (2/2)
 Vòng lặp vô hạn
 Ví dụ:
while (1)
{
cout << "Hello ";
}
----
for ( ; ;) 
{ 
cout << “Hello”; 
} 22
LỆNH BREAK VÀ CONTINUE
 Lệnh break: ép buộc thoát khỏi vòng lặp ngay lập 
tức
 Lệnh continue: bỏ qua phần còn lại trong thân 
vòng lặp (loop body)
 Hai lệnh này vi phạm luồng chạy tự nhiên => chỉ
dùng khi thật cần thiết
23
MINH HỌA LỆNH CONTINUE
24
CẤU TRÚC LẶP LỒNG NHAU
 Nhớ lại: bất kỳ mệnh đề hợp lệ nào trong C++ có thể
được đặt bên trong vòng lặp
 Có thể dùng “{ }” hoặc thụt lề (indent) để biểu diễn
vòng lặp lồng nhau (nested loops)
 Ví dụ:
for (outer=0; outer<5; outer++)
for (inner=7; inner>2; inner--)
cout << outer << inner;
hoặc
for (outer=0; outer<5; outer++)
{
for (inner=7; inner>2; inner--)
{
cout << outer << inner;
}
}
25
BÀI TẬP VỚI CẤU TRÚC LẶP
 Viết chương trình tìm TẤT CẢ các số nguyên tố nhỏ
hơn một số nguyên dương nhập vào từ bàn phím
26
3. MẢNG
3. MẢNG (ARRAY)
 Giới thiệu về mảng
 Mảng khai báo (declaring arrays) và mảng tham chiếu
(referencing arrays)
 Vòng lặp for và mảng
 Mảng trong bộ nhớ
 Mảng trong hàm
 Sử dụng mảng như tham số của hàm hoặc giá trị trả lại
 Lập trình với mảng
 Tìm kiếm (searching), sắp xếp (sorting)
 Mảng nhiều chiều (multidimensional arrays)
28
3.1. GIỚI THIỆU VỀ MẢNG
 Định nghĩa: một tập giá trị có cùng kiểu
 Mảng là một cơ chế lưu trữ phổ biến
 Được sử dụng như danh sách (list) các phần tử:
 Tránh khai báo nhiều biến đơn giản
 Có thể thao tác danh sách như một thực thể (entity)
29
MẢNG KHAI BÁO
 Khai báo mảng là cấp phát một dải vùng nhớ
(allocate memory)
 Cấu trúc: Kiểu Tên_Mảng[Kích_Thước]
 Ví dụ: int score[5];
 Khai báo một mảng gồm 5 số nguyên tên là “score”
 Giống như khai báo 5 biến: int score[0], score[1],
score[2], score[3], score[4];
 Số nguyên dương ở giữa hai dấu [ ] được gọi là
index hoặc subscript, nằm trong khoảng từ 0 đến
(size-1)
 Truy cập các phần tử trong mảng thông qua
index/subscript. Ví dụ: cout << score[3];
30
KHỞI TẠO MẢNG
 Giống như các biến có thể được khởi tạo lúc khai 
báo. Ví dụ: int price = 0; // 0 là giá trị khởi tạo
 Khai báo mảng cũng như thế. 
 Ví dụ: int children[3] = {2, 12, 1}; tương đương
int children[3];
children[0] = 2;
children[1] = 12;
children[2] = 1;
 Nếu số lượng giá trị nhỏ hơn kích thước mảng thì:
Khởi tạo giá trị từ đầu
 Phần còn lại được gán trị 0
 Nếu thiếu kích thước mảng (vd: int b[] = {5, 12, 11};) tự
động khai báo mảng với kích thước dựa trên số lượng giá 
trị khởi tạo
31
VÒNG LẶP FOR VÀ MẢNG
 Vòng lặp đếm tự nhiên duyệt qua tất cả các phần 
tử của mảng
 Ví dụ: 
for(int i = 0; i < 5; i++)
cout << a[i] << “\t”;
32
BÀI TẬP (1/3)
 Viết một chương trình chấp nhận một mảng số nguyên
score có tối đa 5 phần tử. Tìm phần tử lớn nhất của
mảng và in ra khoảng cách từ mỗi phần tử đến
phần tử lớn nhất.
33
BÀI TẬP (2/3)
34
BÀI TẬP (3/3)
35
LƯU Ý
 Phần tử đầu tiên có index là 0
 Lỗi: Out of range, trình biên dịch không báo lỗi 
nhưng lúc chạy có thể sẽ xảy ra thảm họa !
 Dùng constant để khai báo kích thước mảng. Ví 
dụ: 
const int NUMBER_OF_STUDENTS = 5;
int score[NUMBER_OF_STUDENTS];
Trong vòng lặp:
for (idx = 0; idx < NUMBER_OF_STUDENTS; idx++)
{
// Manipulate array
}
lastIndex = (NUMBER_OF_STUDENTS – 1); 36
MẢNG TRONG BỘ NHỚ (1/2)
 Nhớ lại: các biến được cấp phát bộ nhớ với địa chỉ
(address) xác định
 Mảng khai báo cấp phát bộ nhớ cho toàn mảng 
theo kiểu tuần tự (sequentially-allocated)
37
MẢNG TRONG BỘ NHỚ (2/2)
38
SỬ DỤNG MẢNG TRONG HÀM
 Như tham số của hàm
 Phần tử của mảng: giống như một biến đơn giản. Ví dụ: 
void myFunction(double par1); 
int i; double n, a[10];
myFunction(i); // i is converted to double
myFunction(a[3]); // a[3] is double
myFunction(n); // n is double
 Toàn bộ mảng
 Như giá trị trả lại của hàm (sẽ học sau)
39
TRUYỀN TOÀN BỘ MẢNG VÀO HÀM
40
int score[5], numberOfScores = 5;
fillup(score, numberOfScores);
Lưu ý: không có [ ] khi gọi hàm
MẢNG NHƯ THAM SỐ: CÁCH HOẠT ĐÔNG?
 Điều gì thực sự xảy ra?
 Xem mảng gồm 3 thành phần:
 Địa chỉ của phần tử đầu tiên (arrName[0]) 
 Kiểu của các phần tử trong mảng
 Kích thước của mảng
 Chỉ thành phần thứ nhất được truyền vào hàm
 Là địa chỉ của phần tử đầu tiên của mảng
 Tương tự như truyền tham chiếu (pass-by-reference)
41
LƯU Ý
 Phải có tham số là kích thước của mảng
 Không cần [ ] (brackets) khi gọi hàm
 Trong hàm có thể thay đổi giá trị của mảng nên 
đôi khi phải bảo vệ tránh sự thay đổi này bằng 
cách dùng const
42
ỨNG DỤNG CỦA MẢNG (1/2)
 Tìm kiếm (searching)
 Sắp xếp (sorting)
43
ỨNG DỤNG CỦA MẢNG (2/2)
Bài tập:
Viết một chương trình chấp nhận một mảng số thực B có
tối đa 200 phần tử. Hiển thị các phần tử của mảng và sắp
xếp mảng theo chiều tăng dần và hiển thị ra màn hình.
44
MẢNG NHIỀU CHIỀU
 Mảng có thể có nhiều hơn 1 index. 
Ví dụ: char page[30][100];
 Truy cập vào từng phần tử page[i][j]
45
BÀI TẬP
 Bài 1: Cho một mảng hai chiều số thực với tối đa 100
hàng và 100 cột, tính tổng các phần tử chẵn trong mảng
và hiển thị ra màn hình
 Bài 2: Cho một mảng hai chiều số nguyên với đối đa 100
hàng và 100 cột, xét xem mảng có đối xứng qua đường
chéo chính hay không ?
46
4. CON TRỎ
4. CON TRỎ (POINTER)
 Con trỏ
 Biến con trỏ (pointer variables)
 Quản lý bộ nhớ
 Mảng động (dynamic arrays)
 Tạo và sử dụng mảng động
 Phép tính với con trỏ (pointer arithmetic)
48
ĐỊNH NGHĨA CON TRỎ
Con trỏ là địa chỉ trong bộ nhớ của một
biến
Tham số tham chiếu (call-by-
reference) của hàm chính là con trỏ:
địa chỉ của tham số được truyền vào
trong hàm.
49
BIẾN CON TRỎ
 Biến con trỏ là biến kiểu con trỏ (không phải
kiểu int, double, ) dùng để trỏ đến một vùng
nhớ đã được khởi tạo.
 Cú pháp khai báo: Kiểu *Biến_Con_Trỏ;
 Ví dụ:
double *p; // biến p được khai báo là một biến có thể trỏ
đến bất kỳ một vùng nhớ kiểu double (mà không phải kiểu int
hay float)
int *p1, *p2, v1, v2;
50
ĐỊA CHỈ VÀ SỐ (ADDRESSES & NUMBERS)
Con trỏ là một địa chỉ
Địa chỉ (trong vùng nhớ) là một số nguyên
NHƯNG: Con trỏ KHÔNG PHẢI là một số
nguyên !!!
C++ ép buộc con trỏ được sử dụng như một 
địa chỉ
 Không được dùng như một số nguyên
 Mặc dù nó giống như một số nguyên
51
TOÁN TỬ & VÀ * (1/2)
 Toán tử&
 Khi đặt trước một biến sẽ trả về địa chỉ của biến đó
(cũng được xem là một con trỏ trỏ đến biến).
 Thường được gọi là toán tử địa chỉ ("address of"
operator)
 p = &v; nghĩa là con trỏ p được gán bằng địa chỉ
của biến v hay con trỏ p trỏ đến biến v
 Toán tử *
 Khi đặt trước một biến con trỏ sẽ dùng để chỉ định
biến mà con trỏ đấy đang trỏ đến.
 Toán tử * với cách dùng như trên được gọi là toán tử
giải tham chiếu (dereference operator)
 *p nghĩa là “lấy dữ liệu mà p đang trỏ tới”
52
TOÁN TỬ & VÀ * (2/2)
 Kết quả in ra của chương trình sau?:
int *p1, v1 = 0; 
p1 = &v1; // biến con trỏ p1 được gán cho địa chỉ vùng 
nhớ của biến v1
*p1 = 42; // giải tham chiếu p1 và gán 42
cout << v1 << “\t”;
cout << *p1 << endl;
 Có 2 cách để tham chiếu đến biến v1:
 Sử dụng chính bản thân biến v1
 Thông qua con trỏ p1
53
GÁN CON TRỎ (POINTER ASSIGNMENTS)
 int *p1, *p2;
p2 = p1 khác *p2 = *p1 như thế nào?
 p2 = p1
 thay đổi địa chỉ vùng nhớ của con trỏ p2, trỏ tới nơi 
mà p1 đang trỏ tới. p2, p1 lúc này trỏ tới cùng 1 địa 
chỉ.
 *p2 = *p1
 gán giá trị của biến mà p2 đang trỏ tới bằng giá trị của 
biến mà p1 đang trỏ tới. p2, p1 vẫn trỏ tới hai địa chỉ
khác nhau nhưng giá trị tại hai địa chỉ này giờ bằng 
nhau
54
MINH HỌA GÁN CON TRỎ
55
TOÁN TỬ NEW
 Do con trỏ có thể dùng để tham chiếu đến một 
biến => Không cần thiết phải có một định danh 
(không nhất thiết phải có tên)
 Có thể cấp phát động các biến bằng toán tử new, sẽ
tạo ra một biến 
 Không có định danh tham chiếu đến nó 
 Chỉ là một con trỏ
 Ví dụ: int *p; p = new int;
 Tạo ra một biến mới vô danh (không được đặt tên) và 
gán con trỏ p trỏ tới biến đó
 Có thể truy cập biến đó thông qua *p và sử dụng như
một biến thông thường
 int *n; n = new int(17); //Initializes *n to 17 56
57
M
IN
H
H
Ọ
A
T
O
Á
N
T
Ử
N
E
W
CHƯƠNG TRÌNH VỚI NEW (1/2)
58
CHƯƠNG TRÌNH VỚI NEW (2/2)
59
CON TRỎ VÀ HÀM
Con trỏ có thể được sử dụng:
 như tham số của hàm
 như giá trị trả lại của hàm
 int* findOtherPointer(int* p);
Hàm này khai báo:
 Một tham số kiểu con trỏ có thể trỏ tới biến
kiểu int
 Giá trị trả lại là một kiểu con trỏ có thể trỏ tới
biến kiểu int
60
QUẢN LÝ BỘ NHỚ (MEMORY MANAGEMENT)
 Heap (đống)
 Cũng được gọi là “freestore”
 Được dành riêng cho các biến cấp phát động 
(dynamically-allocated) với toán tử new
 Tất cả các biến được cấp phát động sẽ sử dụng bộ nhớ
trong freestore (heap) => nếu có quá nhiều biến động, 
có thể dẫn đến hết bộ nhớ freestore
 Thao tác cấp phát động (với toán tử new) có thể
không thực hiện được nếu freestore bị đầy
61
KIỂM TRA KẾT QUẢ CẤP PHÁT BỘ NHỚ (1/2)
 Với những trình biên dịch cũ, thực hiện 2 bước
1. Kiểm tra liệu giá trị null có được trả về sau khi gọi 
new hay không
int *p;
p = new int;
if (p == NULL)
{
cout << "Error: Insufficient memory.\n";
exit(1);
}
2. Nếu cấp phát thành công thì mới tiếp tục chương 
trình
62
KIỂM TRA KẾT QUẢ CẤP PHÁT BỘ NHỚ (2/2)
Với những trình biên dịch mới, 
nếu hoạt động cấp phát với new bị lỗi:
 Chương trình sẽ tự động ngừng ngay lập 
tức
 Thông báo lỗi
63
TOÁN TỬ DELETE
 Toán tử delete: giải phóng (de-allocate) vùng nhớ động 
đang được trỏ bởi một biến con trỏ.
 Sử dụng khi biến con trỏ không còn cần thiết
 Trả vùng nhớ này về freestore, để sau đó có thể được dùng 
để cấp phát cho biến khác
 Ví dụ: delete p; // giải phóng vùng nhớ được trỏ bởi con 
trỏ p
int *p;
p = new int(5);
// Một vài xử lý
delete p; 
64
CON TRỎ TREO (DANGLING POINTERS)
delete p; giải phóng vùng nhớ động nhưng 
p vẫn trỏ tới đó !
 Dẫn đến con trỏ treo (dangling pointer)
 Điều gì xảy ra khi gọi *p sau đó? 
Tránh con trỏ treo
 Nên gán con trỏ bằng null sau khi delete p
delete p;
p = NULL;
65
BIẾN ĐỘNG VÀ BIẾN TỰ ĐỘNG (DYNAMIC
VS AUTOMATIC VARIABLES)
Biến động (dynamic variables)
 Được tạo với toán tử new
 Được tạo và hủy (destroy) trong lúc chạy chương 
trình
Biến địa phương (local variables)
 Được khai báo bên trong định nghĩa hàm
 Không phải là biến động (not dynamic)
Được tạo khi hàm được gọi
Bị hủy khi lời gọi hàm hoàn tất
 Thường được gọi là các biến tự động (automatic 
variables). Chương trình sẽ kiểm soát các biến 
này cho bạn 66
ĐẶT LẠI TÊN CHO KIỂU CON TRỎ
Giúp bạn tránh việc thêm dấu “*” mỗi khi 
khai báo con trỏ
 typedef int* IntPtr;
 Định nghĩa một kiểu biệt danh mới (alias)
 IntPtr p; tương đương với int *p;
67
THAM SỐ CON TRỎ CALL-BY-VALUE (1/3)
68
THAM SỐ CON TRỎ CALL-BY-VALUE (2/3)
69
THAM SỐ CON TRỎ CALL-BY-VALUE (3/3)
70
MẢNG ĐỘNG (DYNAMIC ARRAYS)
Biến kiểu mảng thực sự là một kiểu con trỏ
Mảng chuẩn với kích thước cố định
Mảng động: 
 Kích thước của mảng không được xác định khi 
lập trình
 Được quyết định trong lúc chạy chương trình
BIẾN KIỂU MẢNG (ARRAY VARIABLES) (1/2)
Mảng được lưu trữ trong bộ nhớ theo địa 
chỉ tuần tự
 Biến mảng tham chiếu đến giá trị đầu tiên của 
mảng
 Do đó biến mảng cũng là một kiểu con trỏ
Ví dụ:
int a[10];
int * p; 
a và p đều là con trỏ
72
BIẾN KIỂU MẢNG (ARRAY VARIABLES) (2/2)
a và p đều là con trỏ => có thể thực hiện 
việc gán
 p = a; // Hợp lệ. p bây giờ trỏ tới nơi mà a đang 
trỏ (tới vị trí đầu tiên của mảng a)
 a= p; // KHÔNG HỢP LỆ. Do con trỏ mảng là 
một CON TRỎ HẰNG SỐ (constant pointer)
a có kiểu constant int*
 Mảng đã được cấp phát trong bộ nhớ
 Biến a PHẢI LUÔN trỏ tới đó! Không thể thay 
đổi!
Đối lập với con trỏ bình thường: có thể
thay đổi địa chỉ trỏ tới
73
MẢNG ĐỘNG
 Những hạn chế của mảng chuẩn
 Phải khai báo kích thước trước, ước lượng kích thước 
tối đa cần thiết
 Có thể lãng phí bộ nhớ
 Mảng động
 Có thể co giãn khi cần thiết
 Tạo mảng động với toán tử new. Cấp phát động 
với biến con trỏ
typedef double * DoublePtr;
DoublePtr d;
d = new double[10]; // Tạo một biến mảng d được cấp 
phát động với 10 phần tử kiểu double 74
XÓA MẢNG ĐỘNG
Được cấp phát động lúc chạy (run-time), vì 
thế nên được hủy lúc chạy
d = new double[10];
 //Xử lý 
delete [] d;
 Giải phóng tất cả bộ nhớ của mảng động
 Dấu ngoặc vuông (brackets) [] ám chỉ đây là 
một mảng
 Tuy nhiên d vẫn chỉ tới vùng nhớ vừa được giải 
phóng => nên đặt lại d = NULL;
75
PHÉP TÍNH VỚI CON TRỎ (POINTER
ARITHMETIC)
 Có thể thực hiện phép tính trên con trỏ: tính toán 
với các địa chỉ
 typedef double* DoublePtr;
DoublePtr d;
d = new double[10];
 d chứa địa chỉ của d[0]
 d + 1 là địa chỉ của d[1]
 d + 2 là địa chỉ của d[2]
 for (int i = 0; i < arraySize; i++)
cout << *(d + i) << " ";
 Chỉ thực hiện phép + - trên con trỏ (không thực 
hiện các phép tính * / với con trỏ)
76
CON TRỎ ĐỘNG NHIỀU CHIỀU
(MULTIDIMENSIONAL DYNAMIC ARRAYS)
Nhớ lại: Mảng của Mảng
 typedef int* IntArrayPtr;
IntArrayPtr *m = new IntArrayPtr[3];
for (int i = 0; i < 3; i++)
m[i] = new int[4];
 Tạo mảng của 3 con trỏ
 Cấp phát cho mỗi con trỏ một mảng 4 phần tử
kiểu int
Kết quả: một mảng động 3x4
77
TÓM TẮT (1/3)
Mệnh đề rẽ nhánh: if-else, switch
Vòng lặp: 
 while, 
 do-while: luôn thực hiện phần thân vòng lặp ít 
nhất 1 lần
 for
Vòng lặp có thể bị ngắt quãng đột ngột với 
hai lệnh: break, continue
78
TÓM TẮT (2/3)
Mảng là tập hợp của dữ liệu cùng kiểu
Phần tử trong mảng được sử dụng như
những biến đơn giản khác
Vòng lặp for là cách tự nhiên để duyệt 
mảng
Chú ý lỗi out-of-range
Các phần tử trong mảng được lưu trữ tuần 
tự
Mảng nhiều chiều
79
TÓM TẮT (3/3)
Con trỏ là một địa chỉ trong bộ nhớ. Cung 
cấp một tham chiếu không trực tiếp đến 
các biến
Biến động: được tạo ra và hủy trong lúc 
chạy chương trình
Freestore: bộ nhớ dành cho các biến động
Mảng cấp phát động: kích thước được quyết 
định khi chạy chương trình
80
THAM KHẢO
 Giáo trình chính: W. Savitch, Absolute C++, 
Addison Wesley, 2002
 Tham khảo:
 A. Ford and T. Teorey, Practical Debugging in C++, 
Prentice Hall, 2002
 Nguyễn Thanh Thủy, Kĩ thuật lập trình C++, NXB 
Khoa học và Kĩ Thuật, 2006
81
File đính kèm:
 bai_giang_ngon_ngu_lap_trinh_bai_2_cac_cau_truc_dieu_khien_m.pdf bai_giang_ngon_ngu_lap_trinh_bai_2_cac_cau_truc_dieu_khien_m.pdf





