Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Tài liệu giảng dạy kỹ thuật lập trình 2
Nội dung xem thử
Mô tả chi tiết
TRƯỜNG CAO ĐẲNG CÔNG NGHỆ THỦ ĐỨC
Khoa Công Nghệ Thông Tin
TÀI LIỆU GIẢNG DẠY
KỸ THUẬT LẬP TRÌNH 2
| 2019 – Lưu hành nội bộ |
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2
LỜI TÁC GIẢ
Quyển giáo trình này được biên soạn dựa theo đề cương
môn học “Kỹ thuật lập trình 2” của Khoa Công nghệ
thông tin Trường Cao đẳng Công nghệ Thủ Đức.
Giáo trình biên soạn sẽ không tránh khỏi những sai sót
về nội dung lẫn hình thức, nhóm biên soạn rất mong
nhận được sự góp ý chân thành từ quý thầy cô và các em
sinh viên để giáo trình hoàn thiện hơn.
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2
MỤC LỤC
Chương 1. Dữ liệu kiểu cấu trúc ...................................................................1
1.1| Khái niệm cấu trúc ........................................................................2
1.2| Khai báo cấu trúc...........................................................................2
1.3| Khai báo biến kiểu cấu trúc...........................................................3
1.4| Truy cập các thành phần trong cấu trúc ........................................5
1.5| Phép toán gán cấu trúc...................................................................6
1.6| Một số ví dụ minh hoạ...................................................................7
1.7| Cấu trúc và hàm.............................................................................9
1.8| Con trỏ tới cấu trúc......................................................................13
1.9| Bài tập..........................................................................................15
Chương 2. MỘT SỐ LỚP THƯ VIỆN CHUẨN C++...............................18
2.1| Lớp xâu ký tự (String Objects)....................................................19
2.2| Lớp nhập, xuất (input, output stream).........................................21
2.3| Luồng tập tin (file stream)...........................................................24
2.4| Bài tập..........................................................................................29
2.5| Bài tập tổng hợp ..........................................................................31
Chương 3. GIỚI THIỆU VỀ PHƯƠNG PHÁP LẬP TRÌNH HƯỚNG
ĐỐI TƯỢNG..................................................................................................33
3.1| So sánh lập trình hướng đối tượng và lập trình cấu trúc .............34
3.2| Khái niệm lập trình hướng đối tượng..........................................36
3.3| Mục tiêu của lập trình hướng đối tượng......................................36
3.4| Các đặc điểm của lập trình hướng đối tượng ..............................37
3.5| Lớp và đối tượng .........................................................................40
3.5.1| Khái niệm đối tượng (Objects)....................................................40
3.5.2| Khái niệm lớp..............................................................................40
3.5.3| Thuộc tính, phương thức .............................................................40
3.5.4| Phân biệt Lớp và Đối tượng ........................................................41
3.6| Biểu diễn lớp ...............................................................................41
3.7| Một số ngôn ngữ hổ trợ lập trình hướng đối tượng.....................42
3.8| Bài tập..........................................................................................43
Chương 4. XÂY DỰNG LỚP ĐỐI TƯỢNG .............................................45
4.1| Cài đặt thuộc tính ........................................................................46
4.2| Cài đặt các hàm thành viên..........................................................48
4.3| Phạm vi truy xuất của Các thành phần trong lớp ........................50
4.4| Cài đặt tính đóng gói ...................................................................52
4.5| Phương thức khởi tạo (constructors)...........................................52
4.6| Phương thức hủy đối tượng (destructors)....................................56
4.7| Phương thức set, get (set, get methods) ......................................58
4.8| Con trỏ this..................................................................................59
4.9| Phương thức hằng (const method)...............................................61
4.10| Phương thức tĩnh .........................................................................64
4.11| Tách biệt giữa khai báo và định nghĩa phương thức ...................67
4.12| Tránh multiple inclusion .............................................................69
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2
4.13| So sánh class và struct.................................................................71
4.14| Sử dụng đối tượng làm tham số cho hàm....................................71
4.15| Con trỏ đối tượng và mảng đối tượng .........................................72
4.16| Đối tượng thành phần..................................................................75
4.17| Từ khóa Friends...........................................................................77
4.17.1| Hàm bạn...................................................................................77
4.17.2| Lớp bạn....................................................................................78
4.18| Bài tập..........................................................................................78
Chương 5. KẾ THỪA VÀ ĐA HÌNH .........................................................85
5.1| Kế thừa trong luồng nhập, xuất (I/O stream Inheritance) ...........86
5.2| Sơ đồ lớp trong I/O stream..........................................................86
5.3| Cerr và clog .................................................................................89
5.4| Tính kế thừa (Inheritance mechanics).........................................89
5.4.1| Khái niệm kế thừa .......................................................................90
5.4.2| Lợi ích của kế thừa ......................................................................91
5.4.3| Đặc tính của kế thừa ....................................................................91
5.4.4| Tổng quát hóa, đặc biệt hóa.........................................................92
5.4.5| Cú pháp khai báo kế thừa ............................................................92
5.4.6| Tầm vực trong kế thừa ................................................................92
5.4.7| Phân loại kế thừa .........................................................................95
5.4.8| Một số mô hình kế thừa:..............................................................96
5.4.9| Diamond problem:.....................................................................100
5.4.10| Virtual base class:..................................................................102
5.4.11| Hàm khởi tạo và hàm hủy .....................................................109
5.4.12| Static binding và Dynamic binding.......................................113
5.4.13| Thành viên Protected.............................................................115
5.5| Đa hình ......................................................................................116
5.5.1| Định nghĩa đa hình ....................................................................116
5.5.2| Phân loại đa hình .......................................................................117
5.5.3| So sánh Overloading và Overriding ..........................................118
5.5.4| Hàm ảo (Virtual function).........................................................120
5.5.5| Hàm ảo thuần (Pure Virtual function), Lớp trừu tượng (Abstract
class) 121
5.6| Bài tập........................................................................................122
Chương 6. Lập trình khái quát.................................................................128
6.1| Khuôn mẫu hàm ........................................................................129
6.1.1| Khái niệm hàm khái quát...........................................................129
6.1.2| Gọi hàm khái quát .....................................................................131
6.1.3| Chồng hàm khái quát.................................................................132
6.2| Khuôn mẫu lớp ..........................................................................133
6.2.1| Khái niệm về Lớp template .......................................................133
6.2.2| Khi nào cần sử dụng class Template .........................................136
6.2.3| Bài tập........................................................................................136
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 1
1. Chương 1. DỮ LIỆU KIỂU CẤU TRÚC
Chương này nhằm giới thiệu cho sinh viên các khái
niệm vềkiểu dữ liệu struct, khai báo và khởi tạo giá
cho biến, truy xuát các thành phần trên struct, sử dụng
struct giải quyết bài toán cụ thể.
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 2
1.1| KHÁI NIỆM CẤU TRÚC
Cấu trúc là kiểu dữ liệu bao gồm nhiều phần tử. Các phần tử của cấu trúc là các
dữ liệu thuộc các kiểu khác nhau và có tên khác nhau. Kiểu cấu trúc được định
nghĩa bởi từ khóa struct. Mỗi phần tử của kiểu dữ liệu cấu trúc được gọi là một
trường.
Dữ liệu kiểu cấu trúc được dùng để mô tả các đối tượng bao gồm các kiểu dữ
liệu khác nhau, như hóa đơn mua hàng, phiếu xuất vật tư, lý lịch nhân viên, phiếu
thu tiền, . . . Các dữ liệu này rất thường gặp trong các bài toán thông tin kinh tế,
quản lý.
Cấu trúc là công cụ để tạo ra kiểu dữ liệu mới. Sau này kiểu cấu trúc mở rộng
thành kiểu lớp.
1.2| KHAI BÁO CẤU TRÚC
Muốn sử dụng kiểu dữ liệu cấu trúc ta phải định nghĩa nó để xác định tên cùng
với các thành phần dữ liệu có trong kiểu cấu trúc này. Một kiểu cấu trúc được
khai báo theo mẫu sau:
struct <tên kiểu>
{
// các thành phần;
} <danh sách biến>;
Mỗi thành phần giống như một biến riêng của kiểu, nó gồm kiểu và tên thành
phần. Một thành phần cũng còn được gọi là trường.
Phần tên của kiểu cấu trúc và phần danh sách biến có thể có hoặc không. Tuy
nhiên trong khai báo kí tự kết thúc cuối cùng phải là dấu chấm phẩy (;).
Các kiểu cấu trúc được phép khai báo lồng nhau, nghĩa là một thành phần của
kiểu cấu trúc có thể lại là một trường có kiểu cấu trúc.
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 3
1.3| KHAI BÁO BIẾN KIỂU CẤU TRÚC
Một biến có kiểu cấu trúc sẽ được phân bố bộ nhớ sao cho các thực hiện của nó
được sắp liên tục theo thứ tự xuất hiện trong khai báo.
Khai báo biến kiểu cấu trúc cũng giống như khai báo các biến kiểu cơ sở dưới
dạng:
struct <tên cấu trúc> <danh sách biến>; // kiểu cũ trong C
hoặc
<tên cấu trúc> <danh sách biến>; // trong C++
Các biến được khai báo cũng có thể đi kèm khởi tạo:
<tên cấu trúc> biến = {giá trị khởi tạo};
Ví dụ:
Khai báo kiểu cấu trúc chứa phân số gồm 2 thành phần nguyên chứa tử số và
mẫu số như sau
struct PhanSo
{
int tuSo;
int mauSo;
};
Kiểu ngày tháng gồm 3 thành phần nguyên chứa ngày, tháng, năm.
struct NgayThang
{
int ngay;
int thang;
int nam;
} xHoliday = {1, 5, 2019};
Một biến xHoliday cũng được khai báo kèm cùng kiểu này và được khởi tạo bởi
bộ số 1. 5. 2019. Các giá trị khởi tạo này lần lượt gán cho các thành phần theo
đúng thứ tự trong khai báo, tức ngay = 1, thang = 5 và nam = 2019.
Kiểu Lop dùng chứa thông tin về một lớp học gồm tên lớp và sĩ số sinh viên. Các
biến kiểu Lop được khai báo là xCNTT, trong đó xCNTT được khởi tạo bởi bộ
giá trị {"CD18TT", 50} với ý nghĩa tên lớp là CD18TT và sĩ số là 50 sinh viên.
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 4
//định nghĩa struct
struct Lop
{
char tenlop[10];
int soluong;
};
//khai báo biến kiểu struct
struct Lop xCNTT = { "CD18TT", 50 };
//hoặc
Lop xCNTT = { "CD18TT", 50 };
Kiểu SinhVien gồm có các trường hoTen để lưu trữ họ và tên sinh viên, ngaySinh
lưu trữ ngày sinh, gioiTinh lưu trữ giới tính dưới dạng số (qui ước 1: nam, 2: nữ)
và cuối cùng trường diem lưu trữ điểm thi của sinh viên. Các trường trên đều có
kiểu khác nhau.
#include<iostream>
using namespace std;
//Khai báo struct
struct NgayThang
{
int ngay;
int thang;
int nam;
};
struct SinhVien
{
char hoTen[25];
NgayThang ngaySinh;
int gioiTinh;
float diem;
};
//Chương trình chính
int main()
{
SinhVien xSV1 = {"NguyenVanBinh",{ 1,1,1980 }, 1 };
SinhVien arrxSV[50];
SinhVien *pSV = arrxSV; //con trỏ trỏ đến mảng
return 0;
}
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 5
Một biến xSV1 được khai báo và khởi tạo giá trị họ tên của sinh viên là
"NguyenVanBinh", ngày sinh là 1/1/1980, giới tính nam (1) và điểm thi để trống.
Khai báo mảng cấu trúc arrxSV có 50 phần tử. Đây là kiểu khởi tạo thiếu giá trị.
Biến con trỏ pSV trỏ đến mảng arrxSV kiểu SinhVien
Ví dụ này còn minh hoạ cho các cấu trúc lồng nhau, cụ thể trong kiểu cấu trúc
SinhVien có một thành phần cũng kiểu cấu trúc là thành phần NgaySinh.
1.4| TRUY CẬP CÁC THÀNH PHẦN TRONG CẤU TRÚC
Để truy nhập vào các thành phần kiểu cấu trúc đối với biến thường ta sử dụng cú
pháp:
• Đối với biến thường:
<tên biến>.<tên thành phần >
• Đối với biến con trỏ kiểu cấu trúc:
<tên biến> → < tên thành phần>
• Đối với các struct lồng nhau:
Truy nhập thành phần ngoài rồi đến thành phần của cấu trúc bên trong, sử
dụng các phép toán. hoặc ➔ (các phép toán lấy thành phần) một cách
thích hợp.
Ví dụ:
int main()
{
SinhVien xSV1 = {"NguyenVanBinh",{1,1,1980 }, 1 };
cout << xSV1.hoTen <<endl;
cout << xSV1.ngaySinh.ngay <<endl;
cout << xSV1.ngaySinh.thang << endl;
return 0;
}
• Đối với biến mảng: Để truy nhập vào các thành phần của biến mảng kiểu
cấu trúc đối ta sử dụng cú pháp:
<tên biến mảng>[<chỉ số mảng>]. <tên thành phần>
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 6
• Đối với biến con trỏ trỏ đến mảng: Để truy nhập vào các thành phần của
biến con trỏ trỏ đến mảng cấu trúc đối ta sử dụng cú pháp:
(<tên con trỏ mảng> + <chỉ số mảng>) ➔ <tên thành phần>
Ví dụ: đoạn code sau minh họa việc truy cập các thành phần của marnng arrxSV
kiểu struct SinhVien bằng cách sử dụng biến mảng thông thường, biến con trỏ
//Chương trình chính
int main()
{
SinhVien arrxSV[2] = {{"Nguyen An", {20,5,1989}, 1},
{"Ly Binh",{15,5,1990},0 } };
SinhVien *pSV = arrxSV; //con trỏ trỏ đến mảng
cout << arrxSV[0].hoTen << arrxSV[0].gioiTinh;
cout << arrxSV[0].ngaySinh.ngay << "/" <<
arrxSV[0].ngaySinh.thang << endl;
cout << (pSV+1)->hoTen << (pSV + 1)->gioiTinh;
cout << (pSV + 1)->ngaySinh.ngay << "/" <<
(pSV + 1)->ngaySinh.thang << endl;
system("pause");
return 0;
}
1.5| PHÉP TOÁN GÁN CẤU TRÚC
Đối với biến kiểu struct chúng ta có thể thực hiện gán giá trị của 2 biến cho nhau.
Phép gán này cũng tương đương với việc gán từng thành phần của cấu trúc. Ví
dụ:
//Chương trình chính
int main()
{
SinhVien xSV1 = {"Nguyen An",{ 20,5,1989}, 1, 8.5 };
SinhVien xSV2 = xSV1;
cout << xSV2.hoTen << endl;
system("pause");
return 0;
}
Lưu ý :không thực hiện phép toán gán trên hai mảng kiểu struct mà phải thực
hiện gán từng phần tử của mảng
int main()
{
SinhVien arrxSV1[2] = { { "Nguyen An",{ 20,5,1989 }, 1
},{ "Ly Binh",{ 15,5,1990 },0 } };
SinhVien arrxSV2[2] = {};
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 7
// arrxSV2 = arrxSV1; không thể thực hiện phép gán trên
biến mảng struct
for (int i = 0; i < 2; i++)
{
arrxSV2[i] = arrxSV1[i];
}
cout << arrxSV2[0].hoTen << endl;
system("pause");
return 0;
}
Chú ý:
✓ Bộ giá trị của biến cấu trúc chỉ được gán ngay khi khởi tạo. Nghĩa là không
gán bộ giá trị cụ thể cho biến cấu trúc sau khi đã khởi tạo biến. Ví dụ:
Sinhvien xSV1 = { "NVA", {1,1,1980}, 1, 7.0};
SinhVien xSV2;
➔ ĐÚNG
xSV2 = { "NVA", {1,1,1980}, 1, 7.0};
➔ SAI
xSV2 = xSV1;
➔ĐÚNG
✓ Không thực hiện phép gán giữa hai mảng cấu trúc.
1.6| MỘT SỐ VÍ DỤ MINH HOẠ
1. Cộng hai phân số được lưu trữ dưới dạng cấu trúc.
#include <iostream>
using namespace std;
struct Phanso
{
int tu;
int mau;
};
int main()
{
Phanso a = { 0,1 };
Phanso b = { 0,1 };
Phanso c = { 0,1 };
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 8
//Input
cout << "Nhap phan so a:" << endl; // nhập a
cin >> a.tu >> a.mau;
cout << "Nhap phan so b:" << endl; // nhập b
cin >> b.tu >> b.mau;
//tính và in c = a+b
c.tu = a.tu*b.mau + a.mau*b.tu;
c.mau = a.mau*b.mau;
cout << "a + b = " << c.tu << "/" << c.mau << endl;
system("pause");
return 0;
}
Nhập danh sách Sinh viên có tối đa 50 phần tử và hiển thị Tên , Điểm của các
Sinh viên trong danh sách vừa nhập
#include <iostream>
#include<iomanip>
using namespace std;
#define MAXSIZE 50
//khai bao struct
struct NgayThang
{
int ngay;
int thang;
int nam;
};
struct SinhVien
{
char hoTen[30];
NgayThang namSinh;
int gioiTinh;
float diem;
};
//chuong trinh chinh
void main()
{
SinhVien arrxSV[MAXSIZE]; //mảng struct
int n = 0; //Số sinh viên
// nhập dữ liệu
cout << "Nhap so luong Sinh vien: ";
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 9
cin >> n;
//nhap mang danh sach co n Sinh vien
for (int i = 0; i < n; i++)
{
cout << "Nhap sinh vien thu " << i <<":";
cin.ignore(1);
cout << "\nHo ten: ";
cin.getline(arrxSV[i].hoTen, 30);
cout << "Ngay sinh: ";
cin >> arrxSV[i].namSinh.ngay
>> arrxSV[i].namSinh.thang
>> arrxSV[i].namSinh.nam;
cout << "Gioi tinh: ";
cin >> arrxSV[i].gioiTinh;
cout << "Diem: ";
cin >> arrxSV[i].diem;
}
//in danh sach
for (int i = 0; i < n; i++)
{
cout <<arrxSV[i].hoTen << setw(30)
<< arrxSV[i].diem << endl;
}
system("pause");
}
Kết quả:
Nhap so luong Sinh vien: 2
Nhap sinh vien thu 0:
Ho ten: Ly Binh
Ngay sinh: 2 1 1990
Gioi tinh: 1
Diem: 6.5
Nhap sinh vien thu 1:
Ho ten: Nguyen Anh
Ngay sinh: 3 10 1980
Gioi tinh: 0
Diem: 9.5
Ly Binh 6.5
Nguyen Anh 9.5
Press any key to continue . . .
1.7| CẤU TRÚC VÀ HÀM
Một cấu trúc có thể được sử dụng để làm đối của hàm dưới các dạng sau đây:
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 10
+ Là một biến cấu trúc, khi đó tham đối thực sự là một cấu trúc.
+ Là một con trỏ cấu trúc, tham đối thực sự là địa chỉ của một cấu trúc.
+ Là một tham chiếu cấu trúc, tham đối thực sự là một cấu trúc.
+ Là một mảng cấu trúc hình thức hoặc con trỏ mảng, tham đối thực sự là
tên mảng cấu trúc.
Ví dụ 1: Cấu trúc hoặc mảng cấu trúc làm đối số cho hàm
Chương trình Nhập danh sách Sinh viên có tối đa 50 phần tử và hiển thị Tên ,
Điểm của các Sinh viên trong danh sách vừa nhập được viết theo dạng hàm như
sau:
#include <iostream>
#include<iomanip>
using namespace std;
#define MAXSIZE 50
//khai bao struct
struct NgayThang
{
int ngay;
int thang;
int nam;
};
struct SinhVien
{
char hoTen[30];
NgayThang namSinh;
int gioiTinh;
float diem;
};
// Khai bao prototypes
void nhapDanhSachSV(SinhVien arrxSV[], int &n);
void inDanhSachSV(SinhVien arrxSV[], int n);
//chuong trinh chinh
void main()
{
SinhVien arrxSV[MAXSIZE]; //mảng struct
int n = 0; //Số sinh viên
//nhap mang danh sach co n Sinh vien
nhapDanhSachSV(arrxSV, n);