Bài giảng Giới thiệu lập trình - Con trỏ - Lê Nguyên Khôi

Tóm tắt Bài giảng Giới thiệu lập trình - Con trỏ - Lê Nguyên Khôi: ...giá trị biến v1, mà p chỉ tới)  Dòng 6: in ra 20 (giá trị biến v2, mà p chỉ tới) Giới Thiệu Lập Trình 1 { 2 int *p, v1, v2; 3 v1 = 10; p = &v1; 4 cout << *p; 5 v2 = 20; p = &v2; 6 cout << *p; 7 } 0x22ff32 p 20 v2 0x22ff32 0x44ab12 p 10 v1 0x44ab12 Toán Tử = 8  Gán...hởi tạo một vùng nhớ mới cho con trỏ p, giá trị tại vùng nhớ này không biết int * p = new int(10);  Khởi tạo một vùng nhớ mới cho con trỏ p, giá trị tại vùng nhớ này được khởi tạo là 10 Giới Thiệu Lập Trình Bài Tập 12Giới Thiệu Lập Trình 1 { 2 int *p1, *p2; 3 p1 = new int; 4 *p1 = 10; ...ng có thể thay đổi sau khi khai báo  Sử dụng lại toán tử new int * a = new int[10]; a = new int[50]; Giới Thiệu Lập Trình Mảng Động – Mảng Tĩnh 16 int * a = new int[10]; int * p;  a và p đều là biến con trỏ, nhưng a là hằng  Có thể gán (được phép) p = a; p chỉ tới địa chỉ mà a đang ...

pdf23 trang | Chia sẻ: havih72 | Lượt xem: 300 | Lượt tải: 0download
Nội dung tài liệu Bài giảng Giới thiệu lập trình - Con trỏ - Lê Nguyên Khôi, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Giới Thiệu Lập Trình
Con Trỏ
TS. Lê Nguyên Khôi
Trường Đại học Công nghệ, ĐHQGHN
Nội Dung
1
 Con trỏ
 Biến kiểu con trỏ
 Quản lý vùng nhớ
 Toán tử con trỏ
 Mảng động
 Khai báo & sử dụng
 Các phép toán với con trỏ
Giới Thiệu Lập Trình
Giới Thiệu
2
 Định nghĩa:
 Địa chỉ vùng nhớ máy tính của một biến
 Vùng nhớ máy tính
 Chia nhỏ thành các byte
 Đánh số thứ tự lần lượt (hệ 16)
 Địa chỉ được sử dụng làm tên cho biến
 Con trỏ đã sử dụng
 Truyền tham số theo kiểu tham chiếu
 Địa chỉ của tham số được truyền
Giới Thiệu Lập Trình
Biến Con Trỏ
3
 Con trỏ là “kiểu dữ liệu”
 Kiểu địa chỉ vùng nhớ
 Có thể dùng biến để lưu giá trị kiểu con trỏ
 Không phải kiểu int, double
Địa chỉ của vùng nhớ dùng lưu dữ liệu kiểu 
int, double
 Ví dụ: double * p;
Khai báo p là biến kiểu con trỏ double
Lưu địa chỉ vùng nhớ kiểu double
Giới Thiệu Lập Trình
Biến Con Trỏ – Khai Báo
4
 Khai báo con trỏ giống biến kiểu dữ liệu khác
 Thêm * vào trước tên biến
 Ký hiệu * phải đặt trước mỗi biến con trỏ
 Ví dụ: int *p1, *p2, v1, v2;
 p1, p2 biến kiểu con trỏ int
 v1, v2 biến kiểu int
 Sử dụng p1, p2 lưu địa chỉ các biến kiểu int
 Sử dụng p1, p2 lưu địa chỉ của v1, v2
Giới Thiệu Lập Trình
Địa Chỉ & Số Nguyên
5
 Con trỏ là địa chỉ
 Địa chỉ là số nguyên
 Con trỏ KHÔNG là số nguyên
 C++ ép con trỏ phải được sử dụng như địa chỉ
 Không thể được sử dụng như số nguyên
Mặc dù đó là số nguyên!!!
Giới Thiệu Lập Trình
Toán Tử &
6
 Toán tử & trả về địa chỉ của biến
 Dòng 4: đặt biến con trỏ p chỉ tới biến v1
 p bằng địa chỉ của v1
 Dòng 5: đặt biến con trỏ p chỉ tới biến v2
 p chỉ tới v1
Giới Thiệu Lập Trình
1 {
2 int *p, v1, v2;
3 v1 = 10; v2 = 20;
4 p = &v1;
5 p = &v2;
6 } 0x22ff32
p
20
v2
0x22ff32
0x44ab12
p
10
v1
0x44ab12
Toán Tử *
7
 Toán tử * truy xuất giá trị của vùng nhớ được 
quản lý (lưu) bởi con trỏ
 Dòng 4: in ra 10 (giá trị biến v1, mà p chỉ tới)
 Dòng 6: in ra 20 (giá trị biến v2, mà p chỉ tới)
Giới Thiệu Lập Trình
1 {
2 int *p, v1, v2;
3 v1 = 10; p = &v1;
4 cout << *p;
5 v2 = 20; p = &v2;
6 cout << *p;
7 }
0x22ff32
p
20
v2
0x22ff32
0x44ab12
p
10
v1
0x44ab12
Toán Tử =
8
 Gán giá trị
 Dòng 3, 4: p chỉ tới v1, q chỉ tới v2
 Dòng 5: sử dụng toán tử * truy cập vùng tới 
nhớ con trỏ quản lý
 *p là v1, *q là v2, dòng 5 tương đương v1 = v2;
Giới Thiệu Lập Trình
1 {
2 int v1 = 10, v2 = 20;
3 int *p = &v1;
4 int *p = &v2;
5 *p = *q;
6 } 0x22ff32
q
20
v2
0x22ff32
0x44ab12
p
10 20
v1
0x44ab12
Toán Tử =
9
 Gán con trỏ
 Dòng 3, 4: p chỉ tới v1, q chỉ tới v2
 Dòng 5: gán p bằng q
 p không quản lý v1
 p và q cùng quản lý v2
Giới Thiệu Lập Trình
1 {
2 int v1 = 10, v2 = 20;
3 int *p = &v1;
4 int *p = &v2;
5 p = q;
6 } 0x22ff32
q
20
v2
0x22ff32
0x44ab12
p
10
v1
0x44ab12
0x22ff32
Bài Tập
10Giới Thiệu Lập Trình
1 {
2 int i = 10, j = 20, k;
3 int *p = &i;
4 int *q = &j;
5 *p += 1;
6 p = &k;
7 *p = *q;
8 p = q;
9 *p = i;
0 }
j
0x7756
p
0x64cc
p
0x16aa
k
0x9948
i
0x2232
Toán Tử new
11
 Sử dụng toán tử new để tạo một vùng nhớ mới 
cho con trỏ, vùng nhớ này không có tên
int * p = new int;
 Khởi tạo một vùng nhớ mới cho con trỏ p, giá 
trị tại vùng nhớ này không biết
int * p = new int(10);
 Khởi tạo một vùng nhớ mới cho con trỏ p, giá 
trị tại vùng nhớ này được khởi tạo là 10
Giới Thiệu Lập Trình
Bài Tập
12Giới Thiệu Lập Trình
1 {
2 int *p1, *p2;
3 p1 = new int;
4 *p1 = 10;
5 p2 = p1;
6 *p2 = 20;
7 p1 = new int;
8 *p1 = 30;
9 }
?p1
?p2
p1
?p2
?
p1
?p2
10
p1
p2
10
p1
p2
20
p1
p2 20
?
p1
p2 20
30
Toán Tử delete
13
 Sử dụng toán tử delete để giải phóng vùng 
nhớ động được tạo ra bởi toán tử new
 Lưu ý: chỉ giải phóng vùng nhớ được tạo ra bởi
new, không phải xóa biến con trỏ p
Giới Thiệu Lập Trình
{
int * p = new int;
delete p;
}
Toán Tử delete
14
 Vùng nhớ động có thể được trả về bởi hàm
 Vùng nhớ động chỉ được giải phóng khi sử 
dụng delete, do đó vùng nhớ động tạo ra 
trong hàm không bị xóa sau khi kết thúc hàm
 Chỉ các biến khai báo trong hàm bị xóa, trong 
đó có biến con trỏ p
Giới Thiệu Lập Trình
int * f(int * q) {
int * p = new int;
return p;
}
Mảng Động 
15
 Biến mảng thực chất là biến con trỏ
 Mảng thông thường (int a[10])
 Độ dài mảng cố định
 Không thể thay đổi độ dài sau khi khai báo
 Có thể coi là con trỏ hằng (con trỏ tĩnh)
 Mảng động (int * a = new int[10])
 Độ dài mảng có thể thay đổi sau khi khai báo
 Sử dụng lại toán tử new
int * a = new int[10];
a = new int[50];
Giới Thiệu Lập Trình
Mảng Động – Mảng Tĩnh 
16
int * a = new int[10];
int * p;
 a và p đều là biến con trỏ, nhưng a là hằng
 Có thể gán (được phép)
p = a;
p chỉ tới địa chỉ mà a đang chỉ tới
 Nhưng không được phép (lỗi dịch)
a = p;
a là hằng, không thay đổi giá trị của a
Giới Thiệu Lập Trình
Nhắc Lại: cstring & Lớp string
17
char aCString[];
string stringVar;
 Chuyển cstring sang string (hợp lệ)
stringVar = aCString;
 Chuyển string sang cstring (không hợp lệ)
aCString = stringVar;
Giới Thiệu Lập Trình
Mảng Động
18
 Hạn chế của mảng thông thường:
 Phải khai báo độ dài trước
 Độ dài mảng có thể không biết tới khi chạy 
chương trình
 Phải ước lượng độ dài lớn nhất
 Lãng phí bộ nhớ
 Mảng động
 Có thể tăng và giảm khi cần thiết
Giới Thiệu Lập Trình
Giải Phóng Mảng Động
19
 Cũng được thực hiện khi chạy
d = new double[10];
 // thao tác với d
delete [] d;
 Giải phóng tất cả bộ nhớ cho mảng động
 [] thông báo giải phóng bộ nhớ cho mảng
 Vẫn chỉ tới vùng nhớ đó
 Nên gán d = NULL;
Giới Thiệu Lập Trình
Bài Tập
20Giới Thiệu Lập Trình
int a[10] = {2,3,5,1,4,7,0};
int *p = a;
cout << a[0] << *p << "\n";
p++;
cout << *p << p[2] << "\n";
p++; a[2] = 0;
cout << p[1] << *p << "\n";
p -= 2;
cout << p[3] << p[1] << "\n";
2 2
3 1
1 9
1 3
Hàm Trả Về Mảng
21
 Kiểu mảng không được phép là kiểu trả về
 Không hợp lệ
int[] someFunction(); 
 Phải trả về kiểu con trỏ
int * someFunction();
Giới Thiệu Lập Trình
Con Trỏ Trong C++
22
 Con trỏ là khối kiến thức đặc biệt quan trọng 
trong C++
 Phải nắm vững khái niệm con trỏ cũng như 
thao tác với con trỏ
 Con trỏ sẽ được sử dụng trong các kiểu dữ 
liệu phức tạp
 INT 2203 Cấu trúc Dữ liệu & Giải thuật
Giới Thiệu Lập Trình

File đính kèm:

  • pdfbai_giang_gioi_thieu_lap_trinh_con_tro_le_nguyen_khoi.pdf