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

Tóm tắt Bài giảng Giới thiệu lập trình - Giới thiệu - Lê Nguyên Khôi: ...<= 5"; Cấu Trúc Lựa Chọn if else loại bỏ trường hợp không cần thiết 20 if (!a && !b) output = false; else if (!a && b) output = true; else if (a && !b) output = true; else if (a && b) output = true; Phân tích và loại trường hợp không cần thiết if (!a && !b) output = false; else output ...p Trình // khai báo hàm trước int main() int A(); int B(); int main() { return 0; } // định nghĩa hàm sau int main() int A() { B(); } int B() { A(); } Hàm – Tính Nhân (Trả Về int) chỉ sử dụng phép cộng 16Giới Thiệu Lập Trình int multiply(int x, int y) { int ketQua = 0; for (i...húc xâu  Ví dụ:  Xâu "hello" lưu dưới dạng cstring  Khai báo char s[10];, s lưu 9 ký tự và '\0'  Lưu xâu sử dụng mảng không đầy:  Khai báo một mảng “đủ lớn” để lưu xâu  Ký tự null ('\0') đánh dấu kết thúc xâu Giới Thiệu Lập Trình Xâu Ký Tự cstring – Ví Dụ 3  Khai báo char s[10];  ...

pdf54 trang | Chia sẻ: havih72 | Lượt xem: 287 | Lượt tải: 0download
Nội dung tài liệu Bài giảng Giới thiệu lập trình - Giới thiệu - Lê Nguyên Khôi, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
outStream.open("outfile.txt");
int so1, so2, so3;
inStream >> so1 >> so2 >> so3;
outStream << "Tong 3 so dau la "
<< (so1 + so2 + so3) << endl;
inStream.close();
outStream.close();
Giới Thiệu Lập Trình
Ghi Dữ Liệu Vào Tệp
13
 Thường một tệp được mở là một tệp rỗng
 Nếu tệp tồn tại, toàn bộ dữ liệu bị xóa
 Mở tệp để chèn vào cuối tệp (sử dụng cờ):
ofstream outStream;
outStream.open("outfile.txt", ios::app);
 Nếu tệp không tồn tại, tạo tệp mới
 Nếu tệp tồn tại, chèn vào cuối tệp
 Tham số thứ 2 là hằng trong lớp ios
Trong thư viện iostream
Không gian tên std
Giới Thiệu Lập Trình
Kiểm Tra Mở Tệp Thành Công
14
 Có thể gặp lỗi khi mở tệp
 Khi tệp không tồn tại (để đọc dữ liệu)
 Không có quyền ghi vào tệp
 Sử dụng hàm thành viên fail()
 Gọi hàm thành viên fail() để kiểm tra mở 
luồng thành công không
inStream.open("infile.txt");
if (inStream.fail()) {
cout << "Loi mo file.\n";
exit(1);
}
Giới Thiệu Lập Trình
Kiểm Tra Kết Thúc Tệp
15
 Dùng vòng lặp để xử lý với tệp đến khi hết tệp
 Sử dụng hàm thành viên eof()
inStream.get(next);
while (!inStream.eof()) {
cout << next;
inStream.get(next);
}
 Đọc từng ký tự cho đến khi hết dữ liệu trong tệp
 Hàm thành viên eof() trả về kiểu bool
Giới Thiệu Lập Trình
Nhập Tên Tệp Khi Chạy Chương Trình
16
 Tham số cho open() là kiểu xâu ký tự
 Tên cụ thể hoặc biến
char tenTep[16];
cout << "Nhap ten tep: ";
cin >> tenTep;
ifstream inStream;
inStream.open(tenTep);
 Linh hoạt hơn đối với tên tệp là biến được 
nhập từ bàn phím khi chạy chương trình
Giới Thiệu Lập Trình
Định Dạng Dữ Liệu Xuất
17
 Xuất dữ liệu dưới dạng 2 số thập phân:
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
 In ra màn hình (12.50)
 Hàm thành viên precision(x)
 Phần thập phân dưới dạng "x" số sau dấu “.”
 Hàm thành viên setf()
 Cho cài đặt nhiều định dạng
 Có thể sử dụng cho bất cứ luồng xuất nào
 Đối với luồng cho tệp, hàm thành viên giống 
đối tượng cout
Giới Thiệu Lập Trình
4Tham Khảo
18
 Đọc sách:
 Chương 8, Lập Trình Cơ Bản C++
 Tìm hiểu thư viện iomanip
 Các định dạng xuất dữ liệu
 Tìm hiểu thao tác với tệp truy cập ngẫu nhiên
 Hiểu quả cho cơ sở dữ liệu lớn
Giới Thiệu Lập Trình
1Giớ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
2Toá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
3Bà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
4Mả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
1Giới Thiệu Lập Trình
Cấu Trúc struct
TS. Lê Nguyên Khôi
Trường Đại học Công nghệ, ĐHQGHN
Nội Dung
1
 Cấu trúc struct
 Kiểu dữ liệu nhóm
 Định nghĩa
 Khai báo / Khởi tạo
 Sử dụng
 Truyền biến cho hàm
Giới Thiệu Lập Trình
Kiểu Dữ Liệu Nhóm
2
 Kiểu Mảng:
 Tập hợp dữ liệu cùng kiểu
 Khai báo sau đó sử dụng như biến đơn lẻ
 Truyền cho hàm: truyền địa chỉ
 Kiểu cấu trúc struct:
 Tập hợp dữ liệu có thể khác kiểu
 Phải định nghĩa trước khi sử dụng
 Khai báo sau đó sử dụng như biến đơn lẻ
 Truyền cho hàm: giống biến đơn lẻ
Giới Thiệu Lập Trình
Kiểu DL Cấu Trúc struct
3
 Tập hợp dữ liệu, có thể khác kiểu, được nhóm
 Mỗi dữ liệu được lưu trong một biến (trường)
 Mỗi dữ liệu có kiểu dữ liệu cụ thể
 Hỗ trợ tổ chức dữ liệu phức tạp vào cùng một 
đối tượng
 Hỗ trợ làm việc giữa các dữ liệu trên đối tượng
Giới Thiệu Lập Trình
Kiểu DL Cấu Trúc struct – Ví Dụ
4
Tên Trường Kiểu Dữ Liệu Dữ Liệu
MSSV string 12345678
HoTen string Trach Van Doanh
NgaySinh string 01/01/1999
GioiTinh bool true
Giới Thiệu Lập Trình
Kiểu DL Cấu Trúc struct – Định Nghĩa
5
 Định nghĩa bởi từ khóa struct
 Định nghĩa toàn cục
 Ngoài và trước int main()
 Tất cả các hàm đều hiểu
 Không được cấp phát bộ nhớ
 Chỉ có mục đích miêu tả cấu trúc
 Chỉ cấp phát bộ nhớ
 Khi khai báo biến kiểu cấu trúc
 Miêu tả:
 Các thành phần (trường) và kiểu của chúng
Giới Thiệu Lập Trình
2struct sinhvien – Định Nghĩa
6
struct sinhvien {
string MSSV;
string HoTen;
string NgaySinh;
bool GioiTinh;
} ;
Giới Thiệu Lập Trình
Tên Trường Kiểu Dữ Liệu Dữ Liệu
MSSV string 12345678
HoTen string Trach Van Doanh
NgaySinh string 01/01/1999
GioiTinh bool true
struct sinhvien – Khai Báo/Khởi Tạo
7
struct sinhvien {
string MSSV;
string HoTen;
string NgaySinh;
bool GioiTinh;
} ;
int main() {
struct sinhvien sv1;
struct sinhvien sv2 = { "12345678" ,
"Trach Van Doanh" ,
"01/01/1999" ,
true } ;
}
Giới Thiệu Lập Trình
Truy Cập Thành Phần struct
8
 Sử dụng toán tử chấm (.)
sv1 . MSSV
sv1 . HoTen
sv1 . NgaySinh
sv1 . GioiTinh
 Gọi tên là “biến thành phần”
 Các thành phần của biến kiểu cấu trúc
 Kiểu cấu trúc struct khác nhau có thể có cùng tên 
biến thành phần
Biến thành phần là biến cục bộ
Giới Thiệu Lập Trình
Truy Cập Thành Phần struct – Ví Dụ
9
struct sinhvien {
string MSSV;
string HoTen;
string NgaySinh;
bool GioiTinh;
} ;
int main() {
struct sinhvien sv1;
sv1.MSSV = "12345678";
sv1.HoTen = "Trach Van Doanh";
sv1.NgaySinh = "01/01/1999";
sv1.GioiTinh = true;
}
Giới Thiệu Lập Trình
struct ngaythangnam
10
struct ngaythangnam {
int ngay;
int thang;
int nam;
} ;
int main() {
struct ngaythangnam homNay = {1, 4, 2000};
struct ngaythangnam ngayMai;
ngayMai.ngay = homNay.ngay + 1;
ngayMai.thang = homNay.thang;
ngayMai.nam = homNay.nam;
}
Giới Thiệu Lập Trình
Cấu Trúc struct – Phép Gán
11
 Với cấu trúc struct ngaythangnam
 Khai báo 2 biến cấu trúc
struct ngaythangnam homQua, homNay;
 Cả 2 biến đều kiểu struct ngaythangnam
 Thực hiện phép gán đơn giản hợp lệ
homQua = homNay;
Sao chép giá trị biến thành phần homNay của cho 
các biến thành phần của homQua, tương đương
homQua.ngay = homNay.ngay;
homQua.thang = homNay.thang;
homQua.nam = homNay.nam;
Giới Thiệu Lập Trình
3Cấu Trúc struct – Phép Toán Khác
12
 Các phép toán khác không được định nghĩa 
cho kiểu cấu trúc struct
 So sánh bằng/khác (==, !=) 
(homQua == homNay biểu thức không hợp lệ)
 So sánh thứ tự (, ...) 
(homQua < homNay biểu thức không hợp lệ) 
 Các phép toán 
(homQua + homNay biểu thức không hợp lệ) 
 Nhập & in
(cin & cout không hợp lệ)
Giới Thiệu Lập Trình
Truyền Biến Cấu Trúc struct Cho Hàm
13
struct toado {
int x, y;
} ;
typedef struct toado ToaDo;
void _nhapToaDo(ToaDo & td) {
cin >> td.x >> td.y;
}
void _inToaDo(const ToaDo & td) {
cout << "(" << td.x << "," << td.y << ")";
}
Giới Thiệu Lập Trình
Truyền Biến Cấu Trúc struct Cho Hàm
14
struct toado { int x , y ; } ;
typedef struct toado ToaDo;
void _nhapToaDo ( ToaDo & td ) ;
void _inToaDo ( const ToaDo & td ) ;
int main ( ) {
ToaDo td1;
_nhapToaDo ( td1 ) ;
_inToaDo ( td1 ) ;
ToaDo td2;
_nhapToaDo ( td2 ) ;
_inToaDo ( td2 ) ;
}
Giới Thiệu Lập Trình
Truyền Biến Cấu Trúc struct Cho Hàm
15
void _trungDiem ( const ToaDo & td1 ,
const ToaDo & td2 ,
ToaDo & trungDiem ) {
trungDiem.x = ( td1.x + td2.x ) / 2;
trungDiem.y = ( td1.y + td2.y ) / 2;
}
ToaDo * _trungDiem ( const ToaDo & td1 ,
const ToaDo & td2 ) {
ToaDo * trungDiem = new ToaDo;
(*trungDiem).x = ( td1.x + td2.x ) / 2;
(*trungDiem).y = ( td1.y + td2.y ) / 2;
return trungDiem;
}
Giới Thiệu Lập Trình
Truyền Biến Cấu Trúc struct Cho Hàm
16
int main ( ) {
ToaDo td1 ;
_nhapToaDo ( td1 ) ;
ToaDo td2 ;
_nhapToaDo ( td2 ) ;
ToaDo tdTrgD1 ;
_trungDiem ( td1 , td2 , tdTrgD1 ) ;
ToaDo * tdTrgD2 = new ToaDo;
tdTrgD2 = _trungDiem ( td1 , td2 ) ;
_inToaDo ( tdTrgD1 ) ;
_inToaDo ( *tdTrgD2 ) ;
}
Giới Thiệu Lập Trình
Cấu Trúc struct & Con Trỏ
17
 Giống các kiểu dữ liệu khác:
 struct toado * là con trỏ tới struct toado
 Toán tử & trả về địa chỉ của biến cấu trúc
 Theo thứ tự ưu tiên: “.” được ưu tiên trước “*”
 Nếu td là con trỏ tới cấu trúc struct toado:
 *p.x tương đương *(p.x) không hợp lệ
 Phải sử dụng (*p).x
 Để thuận tiện, có thể dùng toán tử ->:
kết hợp con trỏ (*) với truy cập trường (.)
p->a tương đương (*p).a
Giới Thiệu Lập Trình
4struct thoigian
18Giới Thiệu Lập Trình
struct thoigian
19Giới Thiệu Lập Trình
struct sohuuti
20Giới Thiệu Lập Trình
struct sohuuti
21Giới Thiệu Lập Trình
struct dathuc
22Giới Thiệu Lập Trình
struct dathuc
23Giới Thiệu Lập Trình
1Giới Thiệu Lập Trình
Hàm – Nâng Cao
TS. Lê Nguyên Khôi
Trường Đại học Công nghệ, ĐHQGHN
Nội Dung
1
 Nhắc lại Hàm – Cơ Bản
 Nạp chồng hàm
 Nạp chồng toán tử
Giới Thiệu Lập Trình
Hàm – Cơ Bản
2
 Khai báo hàm
int bin ( int , int ) ;
 Định nghĩa hàm
int bin ( int so1 , int so2 ) {
// thân hàm miêu tả định nghĩa
// không khai báo lại so1 , so2
}
 Chữ ký hàm
int bin ( int , int )
 Lời gọi hàm
int a = bin ( so1 , so2 ) ;
 Sử dụng tên hàm, tên tham số, không có kiểu
Giới Thiệu Lập Trình
Hàm – Cơ Bản – Truyền Tham Số
3
 Truyền giá trị
int bin ( int , int ) ;
 Tạo và truyền một bản sao > tốn chi phí
 Thay đổi bản sao , bản gốc ngoài hàm không đổi
 Xóa bản sao khi kết thúc hàm
 Truyền tham chiếu
int bin ( int & , int & ) ;
 Chính bản gốc được truyền (địa chỉ bản gốc)
 Thay đổi trong hàm, bản gốc thay đổi
 Không xóa bản gốc khi kết thúc hàm
Giới Thiệu Lập Trình
Hàm – Cơ Bản – Sử Dụng const
4
 Truyền tham chiếu
int bin ( int & , int & ) ;
 Thay đổi trong hàm, bản gốc thay đổi
 Không muốn hàm thay đổi, sử dụng từ khóa const
 Bảo vệ dữ liệu, không cho thay đổi, dữ liệu “chỉ-đọc”
int bin ( const int & , const int & ) ;
 Quy ước:
 Luôn truyền tham chiếu
 Dữ liệu không thay đổi, dùng const
 Dữ liệu thay đổi, không dùng const
Giới Thiệu Lập Trình
Hàm Nạp Chồng (Function Overloading)
5
 Các hàm thực hiện công việc tương tự
 Trùng tên, nhưng khác nhau về tham số
 Số lượng tham số
 Kiểu tham số
 Xác định hàm nào được gọi:
 Sử dụng thông tin về tham số
Số lượng & kiểu tham số
 Kiểu của hàm
Giới Thiệu Lập Trình
2Hàm Nạp Chồng – Ví Dụ
6
void _trungDiem ( const ToaDo & td1 ,
const ToaDo & td2 ,
ToaDo & trungDiem ) {
trungDiem.x = ( td1.x + td2.x ) / 2;
trungDiem.y = ( td1.y + td2.y ) / 2;
}
ToaDo * _trungDiem ( const ToaDo & td1 ,
const ToaDo & td2 ) {
ToaDo * trungDiem = new ToaDo;
(*trungDiem).x = ( td1.x + td2.x ) / 2;
(*trungDiem).y = ( td1.y + td2.y ) / 2;
return trungDiem;
}
Giới Thiệu Lập Trình
Hàm Nạp Chồng
7
 Khác số lượng tham số
 Hàm tính tổng các số truyền vào
 Tính tổng 3 số nguyên
int _tong ( int , int , int ) ;
 Tính tổng 2 số nguyên
int _tong ( int , int ) ;
 Tính tổng 1 số nguyên
int _tong ( int ) ;
 Dựa trên số lượng tham số để gọi hàm tương ứng
Giới Thiệu Lập Trình
Hàm Nạp Chồng
8
 Tham số mặc định
int _tong(int so1, int so2 = 0, int so3 = 0)
{
return so1 + so2 + so3;
}
 Có thể gọi
_tong ( 1 , 2 , 3 )
_tong ( 1 , 2 )
_tong ( 1 )
 Có định nghĩa hàm int _tong ( int , int )
 _tong ( 1 , 2 ) gọi hàm nào
Giới Thiệu Lập Trình
Hàm Nạp Chồng
9
 Khác kiểu tham số
 Hàm tính tổng 2 số truyền vào
int _tong ( int , int ) ;
double _tong ( double , double ) ;
 Dựa trên kiểu tham số để gọi hàm tương ứng
 Tại sao không sử dụng chuyển đổi kiểu tự động
Kiểu trả về không đúng
Nguy hiểm
 _tong(1,2) gọi int _tong(int, int);
 _tong(1.0,2.0) gọi double _tong(double, double);
Giới Thiệu Lập Trình
Hàm Nạp Chồng
10
 Khác kiểu tham số
 Hàm tính tổng 2 số truyền vào
double _tong ( int , double ) ; 
double _tong ( double , int ) ;
 Dựa trên kiểu tham số để gọi hàm tương ứng
 Sử dụng chuyển đổi kiểu tự động
_tong ( 3 , 3 ) hoặc _tong ( 3.5 , 3.5 )
 Gọi hàm nào
 Thêm đầy đủ
int _tong ( int , int ) ;
double _tong ( double , double ) ;
Giới Thiệu Lập Trình
Toán Tử
11
 Toán tử thực chất là hàm
 Sử dụng toán tử giống lời gọi hàm
 Viết theo một cách khác
 Ví dụ: so sánh bằng
 1 == 2 thực chất == ( 1 , 2 )
Giới Thiệu Lập Trình
3Toán Tử Nạp Chồng
12
 Giống như hàm, toán tử cũng có thể nạp chồng
 Định nghĩa toán tử cho kiểu dữ liệu mới
 Nạp chồng toán tử so sánh cho kiểu cấu trúc
struct PS { int ts , ms ; } ;
bool operator == ( const PS & ps1 ,
const PS & ps2 ) {
return ( ps1.ts * ps2.ms
== ps2.ts * ps1.ms ) ;
}
bool operator != ( const PS & ,
const PS & ) ;
Giới Thiệu Lập Trình
Toán Tử Nạp Chồng
13
struct PS { int ts , ms ; } ;
bool operator == ( const PS & ,
const PS & ) ;
bool operator != ( const PS & ,
const PS & ) ;
int main() {
PS ps1 , ps2 ;
// nhập dữ liệu 
if ( ps1 == ps2 ) 
if ( ps1 != ps2 ) 
}
Giới Thiệu Lập Trình
Toán Tử Nạp Chồng
14
struct PS { int ts , ms ; } ;
PS operator + ( const PS & ps1 ,
const PS & ps2 ) {
PS tongPS;
// cập nhật tongPS
return tongPS;
}
int main() {
PS ps1 , ps2 , tongPS ;
tongPS = ps1 + ps2 ;
}
Giới Thiệu Lập Trình
Toán Tử Nạp Chồng
15
struct PS { int ts , ms ; } ;
PS operator + ( const PS & ps ,
const int & i ) {
PS tongPS;
// cập nhật tongPS
return tongPS;
}
int main() {
PS ps , tongPS ;
tongPS = ps + 1 ;
}
Giới Thiệu Lập Trình
Toán Tử Nạp Chồng
16
ostream & operator << ( 
ostream & outStream , 
const PS & ps ) {
outStream << ps.ts << "/" << ps.ms ;
return outStream;
}
int main() {
PS ps , tongPS ;
tongPS = ps + 1 ;
cout << tongPS;
}
Giới Thiệu Lập Trình
Template – Giới Thiệu
17
int _getMax(int so1 , int so2) {
if (so1 < so2) return so2;
return so1;
}
double _getMax(double so1 , double so2) {
if (so1 < so2) return so2;
return so1;
}
PS _getMax(PS so1 , PS so2) {
if (so1 < so2) return so2;
return so1;
}
Giới Thiệu Lập Trình
4Template – Giới Thiệu
18
template 
T _getMax ( T so1 , T so2 ) {
if ( so1 < so2 ) return so2;
return so1;
}
int main() {
PS ps1 , ps2 , psMax;
psMax = _getMax ( ps1 , ps2 ) ;
}
Giới Thiệu Lập Trình

File đính kèm:

  • pdfbai_giang_gioi_thieu_lap_trinh_gioi_thieu_le_nguyen_khoi.pdf