V. Gon trỏ vă Mảng
3. Con trỏ vă mảng hai chiều
Thực tế, bộ nhớ mây tính lưu trữ câc phần tử của mảng hai chiều thănh một dêy câc ơ nhớ liín tiếp giống như mảng một chiều. Vì vậy, việc sử dụng con trỏ để điều khiển mảng hai chiều có m dịng vă n cột tương tự như với mảng một chiều có mxn phần tử.
Cho p trỏ đến mảng hai chiều a[3][3].Như vậy: p trỏ đến phần tử a[0][0] p+1 trỏ đến phần tử a[0][ 1] p+2 trỏ đến phần tử a[0][2] p+4 trỏ đến phăn tử a[ 1 ][0] p+4 trỏ đến phần tử a[ 1 ] [ 1 ]
p+ i*m+j trỏ đến phần tử a[i][j] với m lă số cột của mảng hai chiều
0 1 0
0 • p p+1 p+2
1 p+3 p+4 p+5
2 p+6 p+7 p+8
Như vậy để truy cập đến phần tử thứ a[i][j] ta dùng phĩp toân *(p+ i*m + j), Ví dụ: ta viết lại ứng dụng của Công ty Mambo trong chương I nhưng sử dụng con trỏ p để thao tâc trín mảng mảng thay vì lă thao tâc trực tiếp trín mảng orders. Như vậy giâ trị phần tử orders [region] [month] sẽ được thay bằng *( *(p+region * 3+month) //MAMBOCompany.cpp #include <iostream> using namespace std; int main() {
//khai bâo mảng hai chiều int orders[4][3] = {0}; //con trỏ đơn trỏ đến mảng
int *p = &orders[0][0]; //Nhập dữ liệu cho mâng
for (int region = 0; region < 4; region += 1) for (int month = 0; month < 3; month += 1)
cout« "Number of orders for Region " « region + 1 « ", Month " « month + 1 «":
cin » *(p+region*3+month); I //end for
//end for
//In câc phần tử mảng ra măn hình
for (int region = 0; region < 4; region += 1) {
cout« "Region " « region + 1« " « endl; for (int month = 0; month < 3; month += 1)
cout« " Month " « month + 1
« H. It.
cout« *(p+region*3+month) « endl; } //end for } //end for system("pause"); return 0; } ❖ Tóm tắt chương
J Biến con trỏ lấy địa chỉ của biến mă nó trỏ tới lăm giâ trị của nó J Khai bâo vă khởi tạo biến con trỏ:
float a[5]; float *p=a; inta[3][4J; int *p = &a[0][0];
J Câc phĩp tơn trín con trỏ:
J Sử dụng con trỏ p để truy xuất mảng một chiều như sau:
*p=a[0]; , *(p+i) = a[i];
p = &a[0] p+i = &a[i]
■S Sử dụng con trỏ p để truy xuất mảng hai chiều mxn như sau:
*p=a[0][0]; *(p+i *
n+j) = a[i]0];
p = &a[0][0] (p+i
*
n+j) = &a[i]
J Cấp phât bộ nhớ động vă thu hồi bộ nhớ cho biến đon vă dêy n biến
cùng kiểu:
int *i= new int; delete i;
int *a = new int[n]; delete[] a;
❖ Cđu hỏi củng cố
1. Cho câc khai bâo sau: intx; int * p; int * q;
Câc cđu lệnh sau đđy đúng hay sai? Hêy giải thích tại sao? a. p=q; b. p=56;* c. p=x; d. p=q;** e. q=&x; f. p=q;*
2. Hêy cho biết giâ trị trả về của câc dòng code sau? int x; inty; int * p=&x; int * q=&y; *p=35; *q=98; Kv Thuđt Lđn Trình Trans 25
*p= * q; cout«x«" "«y«endl; cout« * p«" "«*q«endl;
3. Hêy cho biết giâ trị trả về của câc dòng code sau? intx; inty; i'nt * p=&x; int * q=&y; x=35; y=46; p=q; *p=78; ❖ Băi tập
1. Hêy khai bâo biến kí tự ch vă con trỏ kiểu kí tự pc trỏ văo biến ch. Viết ra câc câch gân giâ trị ‘ A’ cho biến ch.
2. Cho mảng nguyín cost. Viết ra câc câch gân giâ trị 100 cho phần tử thứ 3 của mảng.
3. Cho p, q lă câc con trỏ cùng trỏ đến kí tự c. Đặt p = 'q + 1. Có thể khẳng định: q = p - 1 ?
* *
* *
4. Cho p, q lă câc con trỏ trỏ đến biến nguyín X = 5. Đặt p = q + 1; Hỏi *q ?
* *
5. Cho p, q, r, s lă câc con trỏ trỏ đến biến nguyín X = 10. Đặt q = p + 1; r = q + 1; s = r + 1. Hỏi giâ trị của biển X ?
* *
* * * *
6. Chọn cđu đúng nhất trong câc cđu sau:
a. Địa chỉ của một biến lă số thứ tự của byte đầu tiín mây dănh cho biến đó.
b. Địa chỉ của một biến lă một số nguyín.
c. Số học địa chỉ lă câc phĩp tơn lăm việc trín câc số nguyín biểu diễn địa chỉ của biến
d. a vă b đúng
7. Chọn cđu sai trong câc cđu sau:
a. Câc con trỏ có thể phđn biệt nhau bởi kiếu của biến mă nó trỏ đến.
b. Hai con trỏ trỏ đến câc kiểu khâc nhau sẽ có kích thước khâc nhau.
c. Một con trỏ kiểu void có thể được gân bởi con trỏ có kiểu bất Kỳ (cần ĩp kiểu).
d. Hai con trỏ cùng trỏ đến kiểu cấu trúc có thể gân cho nhau. 8. Cho con trỏ p trỏ đến biến X kiểu float. Có thể khẳng định ?
a. p lă một biến vă p cũng lă một biến* b. p lă một biến vă p lă một giâ trị hằng*
c. Để sử dụng được p cần phải khai bâo float p; vă gân p = x;* * d. Cũng có thể khai bâo void p; vă gân (float)p = &x;*
9. Cho khai bâo float X, y, z, px, py; vă câc lệnh px = &x; py = &y; Có thể khẳng định ? * * a. Neu X = px thì y = py* * b. Neu X = y + z thì px = y + z* c. Neu px = y + z thì px = py + z* * * d. a, b, c đúng
10. Cho khai bâo float X, y, z, px, py; vă câc lệnh px = &x; py = &y; Có thể khẳng định ? * * a. Neu px = X thì py = y* * b. Neu px* = py - z thì px = y - z* * c. Neu px = y- zthìx = y- z* d. a, b, c đúng
11. Không dùng mảng, hêy nhập một dêy số nguyín vă in ngược dêy ra măn hình.
12. Khơng dùng mảng, hêy nhập một dêy số nguyín vă chỉ ra vị trí của số bĩ nhất, lớn nhất.
13. Không dùng mảng, hêy nhập một dêy số nguyín vă in ra dêy đê được sắp xếp.
14. Không dùng mảng, hêy nhập một dêy kí tự. Thay mỗi kí tự ‘a’ trong dêy thănh kí tự ‘b’ vă in kết quả ra măn hình
15. Lăm lại câc băi tập ở chương I dùng kỹ thuật con trỏ.
CHƯƠNG 3: ĐỆ QUY
Mục tiíu:
Sau khi học xong chương năy Sinh viín có khả năng:
Trình băy khâi niệm về đệ qui
Trình băy câc ưu nhược điểm của hăm đệ qui Viết một sổ hăm đệ qui đơn giăn
I. Định nghĩa đệ quỵ 1. Định nghĩa
Đệ quy lă kỹ thuật tìm lời giải của một băi tôn bằng câch tìm lời giải của băi tôn nhỏ hơn. Đệ quy lă câch giải rất hữu dụng trong việc tìm lời giải của những băi toân phức tạp.
Ngoăi ra, hai điều kiện quan trọng để có thể giải băi tôn bằng đệ quy lă băi toân tồn tại bước đệ quy vă phải có điều kiện dừng. Trong tôn học, băi tơn tính giai thừa của một số ngun khơng đm:
Tính S(n) = 1 T 2 + 3 + ... + (n- 1) + n
Ta nhận thấy: 1 + 2 + 3 + ... + (n=- 1) = S(n - 1) S(n) = S(n - 1) + n Hơn nữa, S(0) = 0.
Vậy, băi toân tồn tại bước đệ quy vă có điều kiện dừng.
Một hăm được gọi lă đệ quy nếu bín trong thđn của hăm đó có lời gọi hăm lại chính nó một câch trực tiếp hay giân tiếp.
Khi thực hiện một hăm đệ qui, hăm sẽ phải chạy rất nhiều lăn, trong mỗi lần chạy chương trình sẽ tạo nín một tập biến cục bộ mới trín ngăn xếp (câc đối, câc biến riíng khai bâo trong hăm) độc lập với lần chạy trước đó, từ đó dễ gđy trăn ngăn xíp. Vì vậy đơi với những băi tơn có thí giải được'băng phương phâp lặp thì khơng nín dùng đệ qui.
2. Phđn loại đệ quy
Có bốn loại đệ quy:
- Đệ quy tuyến tính: Trong thđn hăm có duy nhất một lời gọi
hăm gọi lại chính nó một câch tường minh.
- Đệ quy nhị phđn: Trong thđn hăm có hai lời gọi hăm gọi lại
chính nó một câch tường minh.
■ - Đệ quy hổ tương: Trong thđn hăm năy có lời gọi hăm tới hăm
kia vă bín trong thđn hăm kia có lời gọi hăm tới hăm năy.
- Đệ quy phi tuyến: Trong thđn hăm có lời gọi hăm lại chính nó
được đặt bín trong thđn vịng lặp.