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 ...
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:
- bai_giang_gioi_thieu_lap_trinh_con_tro_le_nguyen_khoi.pdf