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
Trang 1TRƯỜ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ộ |
Trang 2Tà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
Trang 3Tà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
Trang 4Tà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
Trang 5Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 1
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ể
Trang 6Tà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>
Trang 7Tà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};
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
Trang 8Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 4
Trang 9Tà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:
• Đố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;
Trang 10Tà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;
Trang 11Tà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++)
Trang 12Tà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;
SinhVien arrxSV[MAXSIZE]; //mảng struct
int n = 0; //Số sinh viên
// nhập dữ liệu
cout << "Nhap so luong Sinh vien: ";
Trang 13Tà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++)
}
//in danh sach
for (int i = 0; i < n; i++)
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
Trang 14Tà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:
// Khai bao prototypes
void nhapDanhSachSV(SinhVien arrxSV[], int &n);
void inDanhSachSV(SinhVien arrxSV[], int );
//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);
Trang 15Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 11
//Ham nhap danh sach Sinh vien
void nhapDanhSachSV(SinhVien arrxSV[MAXSIZE], int &n)
{
// nhập dữ liệu
cout << "Nhap so luong Sinh vien: ";
cin >> n;
//nhap danh sach
for (int i = 0; i < n; i++)
>> arrxSV[i].namSinh.nam;
cout << "Gioi tinh: "; cin >> arrxSV[i].gioiTinh;
cout << "Diem: "; cin >> arrxSV[i].diem;
}
}
//ham in danh sach Sinh vien
void inDanhSachSV(SinhVien arrxSV[MAXSIZE], int n)
Trang 16Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 12
Hàm tìm Sinh viên có điểm cao nhất trong danh sách Sinh viên được tạo trong
// Khai bao prototypes
void nhapDanhSachSV(SinhVien arrxSV[], int &n);
void inDanhSachSV(SinhVien arrxSV[], int );
SinhVien timDiemMax(SinhVien arrxSV[MAXSIZE], 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);
(arrxSV, n);
//in danh sach
SinhVien xSVMax = timDiemMax(arrxSV, n);
cout << "Diem Trung binh lon nhat la: "
<< xSVMax.diem << endl;
system("pause");
}
//Ham nhap danh sach Sinh vien
//ham in danh sach Sinh vien
Trang 17Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 13
//ham tim sinh vien co diem cao nhat
SinhVien timDiemMax (SinhVien arrxSV[MAXSIZE], int n)
{
float nM = arrxSV[0].diem; //Diem max
int nVT = 0; //Phan tu max
for (int i = 1; i < n; i++)
{
if (nM < arrxSV[i].diem) {
nM = arrxSV[i].diem;
nVT = i;
} }
return arrxSV[nVT];
}
Kết quả:
Nhap so luong Sinh vien: 3
Nhap sinh vien thu 0:
Diem Trung binh lon nhat la: 10
Press any key to continue
1.8| CON TRỎ TỚI CẤU TRÚC
Khi khai báo biến con trỏ, ngoài các kiểu dữ liệu thông thường như int, float, double, … ta có thể khai báo biến con trỏ kiểu cấu trúc Như sau:
Trang 18Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 14
void main()
{
SinhVien arrxSV[MAXSIZE]; //mảng struct
SinhVien *pSV = arrxSV; //bien con tro tro den mang
int n = 0; //Số sinh viên
//nhap mang danh sach co n Sinh vien
nhapDanhSachSV(pSV, n);
//in danh sach
SinhVien xSVMax = timDiemMax(pSV, n);
cout << "Diem Trung binh lon nhat la: " << xSVMax.diem; system("pause");
}
Nhap so luong Sinh vien: 2
Nhap sinh vien thu 0:
Diem Trung binh lon nhat la: 9.5
Press any key to continue
Ta có thể sử dụng biến con trỏ để truy cập các thành phần bên trong biến cấu trúc bằng hai cách:
<tên con trỏ> ➔ <thành phần>
Hoặc:
(* <tên con trỏ>).<thành phần>
Ví dụ: hai câu lệnh sau là tương đương
cout << "Diemlon nhat la: " << (*pSVMax).diem << endl;
Trang 19Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 15
cout << "Diem lon nhat la: " << pSVMax->diem << endl;
định
BÀI TẬP TẠI LỚP
Câu 1 Viết chương trình để quản lý các gói cước sử dụng 3G của nhà mạng
Viettel Biết rằng mỗi gói cước cần lưu trữ các thông tin sau:
• Tên gói: do người dùng nhập vào từ bàn phím, gồm tối đa 10 ký tự Ví
dụ: MIMAX1, MIMAX3, MIMAX6
• Chu kỳ gói: chương trình tự động tính từ tên gói Biết chu kỳ là số ngày
thuê bao được sử dụng Tùy theo ký tự cuối trong Tên gói là 1, 3 hay 6 tương ứng với số số ngày là 30, 90 hay180
• Giá gói: là số tiền người dùng phải trả cho một chu kỳ của gói 3G Giá trị
do người dùng nhập, tối đa 6 chữ số Ví dụ: 70000, 210000, 420000
• Vượt gói: là giá trị logic do người dùng nhập từ bàn phím để báo cho hệ
thống biết ngắt (1) hoặc không ngắt (0) kết nối khi người dùng sử dụng hết lưu lượng tốc độ cao của gói cước 3G
Xây dựng và thực thi các chức năng sau:
a Nhập danh sách gồm n gói cước
b Xuất danh sách ra màn hình
Câu 2
Chương trình quản lý danh sách và thông tin các khách hàng là thuê bao sử dụng 3G của nhà mạng Viettel bao như sau:
− Thông tin về Gói cước gồm:
• Tên gói: do người dùng nhập vào từ bàn phím, gồm tối đa 10 ký tự Ví
dụ: MIMAX1, MIMAX3, MIMAX6
Trang 20Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 16
• Chu kỳ gói: chương trình tự động tính từ tên gói Biết chu kỳ là số ngày
thuê bao được sử dụng Tùy theo ký tự cuối trong Tên gói là 1, 3 hay 6 tương ứng với số số ngày là 30, 90 hay180
• Giá gói: là số tiền người dùng phải trả cho một chu kỳ của gói 3G Giá trị
do người dùng nhập, tối đa 6 chữ số Ví dụ: 70000, 210000, 420000
• Vượt gói: là giá trị logic do người dùng nhập từ bàn phím để báo cho hệ
thống biết ngắt (1) hoặc không ngắt (0) kết nối khi người dùng sử dụng hết lưu lượng tốc độ cao của gói cước 3G
− Thông tin về Thuê bao gồm:
• Họ tên: là chuỗi không bao gồm khoảng trắng, viết hoa đầu từ
• Số CMND: là chuỗi gồm 9 ký tự số do người dùng nhập vào từ bàn phím
• Các Thông tin về gói 3G gồm Tên gói, Chu kỳ gói, Giá gói, Vượt gói Yêu cầu:
1 Hãy tổ chức và khai báo các struct cho chương trình
2 Viết hàm nhập các thông tin của thuê bao gồm: Họ tên, Số CMND, Tên gói, Giá gói, Vượt gói
3 Viết hàm hiển thị các thông tin của thuê bao vừa nhập ra màn hình
4 Viết hàm main gọi tất cả các hàm đã có trong chương trình
BÀI TẬP VỀ NHÀ
Chương trình quản lý danh sách và thông tin các khách hàng là thuê bao sử dụng dịch vụ truyền hình FPT như sau:
− Thông tin về Gói cước TV gồm:
• Tên gói: do người dùng nhập vào từ bàn phím, gồm tối đa 4 ký tự Ví dụ:
16TV, 22TV, 27TV
• Tốc độ: chương trình tự động tính từ tên gói Biết tốc độ là hai số đầu tiên
trong Tên gói Ví dụ Tên gói là 16TV thì tốc độ có giá trị là 16 (Mbps),
…
• Giá gói: là số tiền người dùng phải trả cho một chu kỳ của gói 3G Giá trị
do người dùng nhập, tối đa 6 chữ số Ví dụ: 265.000, 305.000, 365.000
• Phí hòa mạng: là dữ liệu dạng số do chương trình tự động tính theo Quận
Biết quận 1, 3, 5, 7 phí hòa mạng là 700.000 đồng, các quận khác phí là
0 đồng
− Thông tin về Thuê bao TV gồm:
• Họ tên: là chuỗi không bao gồm khoảng trắng giữa chuỗi
• Số CMND: là chuỗi gồm 9 ký tự số do người dùng nhập vào từ bàn phím
• Quận: là dữ liệu dạng chuỗi do người dùng nhập vào tối đa 10 ký tự
• Gói cước sử dụng: bao gồm thông tin: Tên gói, Tốc độ, Giá gói, Phí hòa
mạng
Yêu cầu:
1 Hãy tổ chức và khai báo các struct cho chương trình
2 Viết hàm nhập các thông tin của thuê bao gồm: Họ tên, Số CMND, Quận, thông tin gói cước sử dụng gồm: Tên gói, Giá gói
3 Viết hàm hiển thị các thông tin của thuê bao vừa nhập ra màn hình
Trang 21Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 17
4 Viết hàm tính Phí hòa mạng biết khách hàng ở các quận 1, 3, 5, 7 phí hòa mạng là 700.000 đồng, các quận khác phí là 0 đồng
5 Viết hàm tính giá cho trường Tốc độ biết rằng giá trị tùy theo hai ký số đầu trong Tên gói tương ứng với giá trị là 16, 22 hay 27
6 Viết hàm main gọi tất cả các hàm đã có trong chương trình
Lưu ý: Trình bày code theo chuẩn
Trang 22Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 18
CHUẨN C++
Chương 3
Chương này nhằm giới thiệu cho sinh viên một số lớp thư viện chuẩn trong C++ như: string objects, input/output stream, file stream Qua đó sinh viên có khả năng sử dụng các lớp thư viện được xây dựng sẵn trong C++
Trang 23Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 19
Mô hình hướng đối tượng cho đầu vào và đầu ra (I / O) là một tập các lớp (classes) và các header files được cung cấp bởi Thư viện C ++ chuẩn Các lớp này thực hiện và quản lý các bộ đệm luồng (stream bufer) và dữ liệu được giữ trong các bộ đệm Bộ đệm giữ các dữ liệu input và output, cho phép chương trình thao tác và định dạng dữ liệu
2.1| LỚP XÂU KÝ TỰ (STRING OBJECTS)
Một chuỗi là một dãy các ký tự, thường sử dụng như các từ hoặc tên.Thư viện C++ chuẩn cung cấp lớp đối tượng String Để sử dụng đối tượng string người dùng phải khai báo tiền xử lý:
#include <string>
string class là một phần của tên miền chuẩn (standard namespace), sử dụng theo
cách std::string Nếu khai báo thêm
− Khởi tạo chuỗi rỗng
string sName(); // hoặc
string sName = “”;
− Gán chuỗi Jane cho biến sName
string sName = “Jane”; //hoặc
string sName (“Janes”);
− Gán gán giá trị biến chuỗi sName cho sTemp
string sTemp = sName; // hoặc
Trang 24Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 20
string sTemp (sName);
sName là chuỗi “Thu Duc”
Lớp string cung cấp các phương thức (methods) sau:
operator=(newString) Gán chuỗi newString cho chuỗi
sName.operator=("Cao Dang"); //gan chuoi
cout << sName << endl;
Trang 25Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 21
cout << sName[0] << endl; // C
cout << sName.at(0) << endl; // C
sName.operator+=("Thu Duc"); // sName thanh "Cao Dang Thu Duc"
cout << sName.length() << endl; // 15
cout << sName.size() << endl; //15
cout << sName.find("Dang") << endl; //4
cout << (sName.substr(4, 4)) << endl; //"Dang"
cout << sName.empty() <<endl; //Kiem tra chuoi co rong hay khong
sName.clear(); //Xoa các ky tu trong chuoi
cout << sName.length() << endl; //0
2.2| LỚP NHẬP, XUẤT (INPUT, OUTPUT STREAM)
Chúng ta đã sử dụng đối tượng iostream trước đây std::cout là đối tượng output stream object để in ra màn hình std::cin là đối tượng input stream để nhận dữ liệu từ bàn phím
Tương đương với std::cout là std::ostream, và std::cin là std::istream
Cũng như các đối tượng khác, std::cout và std::cin có các phương thức Toán tử
<< và >> operators thực tế là hai phương thức operator<< và operator>> Đoạn code sau:
Trang 26Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 22
Dòng lệnh gọi phương thức operator<< truyền giá trị cho biến x
Hai câu lệnh sau tương đương:
// I hope the user does the right thing!
std::cout << "Please enter an integer: ";
std::cin >> nNum;
std::cout << "You entered " << nNum << '\n';
}
Kết qủa chương trình trên hoạt động tốt hay không phụ thuộc vào dữ liệu người
dùng nhập vào Giả sử người dùng không nhập số nguyên 5 mà nhập từ “five”
thì kết quả chương trình sẽ ra sao? Chúng ta có thể sử dụng một số phương thức
trong std::cin để làm tăng khả năng của chương trình là chẩn đoán dữ liệu input
lỗi và cung cấp dữ liệu có thể chấp nhận được trong đoạn code sau:
#include <iostream>
#include <limits>
int main() {
int x;
// I hope the user does the right thing!
std::cout << "Please enter an integer: ";
// Enter and remain in the loop as long as the user provides // bad input
while (!(std::cin >> nNum)) {
// Report error and re-prompt
std::cout << "Bad entry, please try again: ";
// Clean up the input stream
std::cin.clear(); // Clear the error state of the stream // Empty the keyboard buffer
Trang 27
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 23
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); }
std::cout << "You entered " << x << '\n';
Tuy nhiên các ký tự mà người dùng nhập vào có thể không được lưu trữ trên bộ
đệm bàn phím như trong đoạn code sau:
Please enter a line of text: Mary had a little lamb
You entered: Mary
Sử dụng phương thức getline để đọc toàn bộ dòng vào biến sLine như sau:
Trang 28Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 24
'\n';}
Please enter a line of text: Mary had a little lamb You entered: Mary had a little lamb
2.3| LUỒNG TẬP TIN (FILE STREAM)
Nhiều ứng dụng cho phép người dùng có thể tạo và thao tác trên dữ liệu Các ứng dụng thực sự hữu ích khi cho phép người dùng có thể lưu trữ dữ liệu trên tập tin Ví dụ các bộ xử lý chữ có thể tải và lưu dữ liệu
Các vector trở nên hữu ích hơn khi chúng tồn tại liên tục Trong suốt quá trình chương trình thực thi để người dùng có thể khởi tạo và thao tác trên vector; Có thể lưu dữ liệu trên vector vào trong ổ đĩa và thoát chương trình; Sau đó người dùng có thể chạy lại chương trình và tải các vector từ trong ổ đĩa để tiếp tục làm việc Đối tượng fstream trong C++ hổ trợ việc này
Ví dụ sau cho phép người dùng lưu nội dung của một vector vào file và tải vector
void print_vector(const std::vector<int>& vec);
void save_vector(const std::string& filename, const
std::vector<int>& vec);
void load_vector(const std::string& filename,
std::vector<int>& vec);
//main
int main() {
std::vector<int> list;
bool done = false;
char command = '\0';
while (!done) {
std::cout << " Insert <item> \n Print \n"
<< " Save <filename> \n Load
<filename> \n"
<< " Erase \n Quit: ";
Trang 29Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 25
std::cin >> command;
int value = 0;
std::string filename;
switch (command) { case 'I':
print_vector(list);
break;
case 'S': case 's':
std::cin >> filename;
save_vector(filename, list);
break;
case 'L': case 'l':
std::cin >> filename;
load_vector(filename, list);
break;
case 'E': case 'e':
list.clear();
break;
case 'Q': case 'q':
done = true;
break;
} }
}
/* print_vector(v) : Prints the contents of vector v v
is a vector holding integers.*/
void print_vector(const std::vector<int>& vec){
Trang 30Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 26
void save_vector(const std::string& filename, const
std::vector<int>& vec)
}
out << '\n'; }
/* load_vector(filename, v): Reads the contents of
vector v from text file filename v's contents are
replaced by the file's contents If the file cannot be found, the vector v is empty v is a vector holding
integers
*/
void load_vector(const std::string& filename,
std::vector<int>& vec)
{
// Open a text file for reading
std::ifstream in(filename);
if (in.good())
{ // Make sure the file was opened properly
vec.clear(); // Start with empty vectorint value = 0;
while (in >> value) // Read until end of file
{
vec.push_back(value);
}
Trang 31Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 27
std::cout << "Unable to load in the file\n"; }
}
Lưu ý là tham số truyền cho các hàm save_vector và load_vector ở dạng tham chiếu đến hằng chuỗi std::string Nghĩa là các hàm không thể thay đổi nội dung của chuỗi được truyền vào
Đối tượng std::ofstream cho phép lưu dữ liệu vào file bằng câu lệnh: std::ofstream out(filename);
Đối tượng tên out được liên kết đến file văn bản có tên filename Có thể viết thành hai câu lệnh như sau:
Lập trình viên cần kiểm tra chắc chắn rằng file đã được mở đúng các bằng cách
dùng phương thức good với giá trị trả về true hoặc false Sau khi file liên kết
đến file, có thể sử dụng đối tượng std::ofstream giống như đối trượng std::cout, thay vì dữ liệu được in ra màn hình thì lưu vào file Tương tự std::cout, toán tử
<< chuyển dữ liệu đến luồng ra std::ofstream kể cả std::setw
Sau khi ghi dữ liệu xuống file xong, chương trình tự động đóng file Lớp std::ofstream cung cấp phương thức close để kiểm tra file đóng thành công hay không
Việc sử dụng kết thúc file bằng ‘\n’ cho hiệu xuất xử lý nhanh hơn gấp ba lần so với sử dụng std::endl Quan sát ví dụ sau:
#include <iostream>
#include <fstream>
Trang 32Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 28
#include <ctime>
#include <vector>
#include <cstdlib>
// Make a convenient alias for the long type name
using Sequence = std::vector<int>;
Sequence make_random_sequence(int size, int max);
void print_with_endl(const Sequence& vs, std::ostream& out);
void print_with_n(const Sequence& vs, std::ostream&
auto seq = make_random_sequence(10000, 100);
// Time writing the elements to the console with std::endl newlines
clock_t start_time = clock();
print_with_endl(seq, std::cout);
unsigned elapsed1 = clock() - start_time;
// Time writing the elements to the console with '\n' newlines
start_time = clock();
print_with_n(seq, std::cout);
unsigned elapsed2 = clock() - start_time;
// Time writing the elements to a text file with std::endl newlines
std::ofstream fout("temp.out");
start_time = clock();
print_with_endl(seq, fout);
fout.close();
unsigned elapsed3 = clock() - start_time;
// Reopen the file for writing
unsigned elapsed4 = clock() - start_time;
std::cout << "With std::endl (console): " <<
Trang 33Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 29
Sequence make_random_sequence(int size, int max)
{
Sequence result(size);
for (int i = 0; i < size; i++)
}
2.4| BÀI TẬP
Trang 34Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 30
II Chuẩn đầu ra cần đạt:
thư viện hữu ích
a Nhập danh sách n sinh viên từ file input.txt
b Xuất danh sách sinh viên ra màn hình
c Tìm và ghi ra file (output.txt) danh sách những sinh viên có cùng họ
“Nguyen”
BÀI TẬP NÂNG CAO
Chương trình quản lý danh sách và thông tin các khách hàng là thuê bao sử dụng dịch vụ truyền hình FPT như sau:
− Thông tin về Gói cước TV gồm:
• Tên gói: do người dùng nhập vào từ bàn phím, gồm tối đa 4 ký tự Ví dụ:
16TV, 22TV, 27TV
• Tốc độ: chương trình tự động tính từ tên gói Biết tốc độ là hai số đầu tiên
trong Tên gói Ví dụ Tên gói là 16TV thì tốc độ có giá trị là 16 (Mbps),
…
• Giá gói: là số tiền người dùng phải trả cho một chu kỳ của gói 3G
Trang 35Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 31
• Phí hòa mạng: là dữ liệu dạng số do chương trình tự động tính theo Quận
Biết quận 1, 3, 5, 7 phí hòa mạng là 700.000 đồng, các quận khác phí là
0 đồng
− Thông tin về Thuê bao TV gồm:
• Họ tên: là chuỗi bao gồm khoảng trắng giữa chuỗi
• Số CMND: là chuỗi gồm 9 ký tự số
• Quận: là dữ liệu dạng chuỗi bao gồm khoảng trắng
• Gói cước sử dụng: bao gồm thông tin: Tên gói, Tốc độ, Giá gói, Phí hòa
mạng
Yêu cầu:
7 Hãy tổ chức và khai báo các struct cho chương trình
8 Viết hàm nhập các thông tin của thuê bao từ file input.ini
9 Viết hàm hiển thị các thông tin của thuê bao vừa nhập ra màn hình
10 Viết hàm cho phép sửa lại giá gói của khách hàng tên x thành giá y (x, y được cấp từ bàn phím) Sau đó cập nhật danh sách thuê bao vào file
input.ini
11 Viết hàm main gọi tất cả các hàm đã có trong chương trình
Lưu ý: Trình bày code theo chuẩn
2.5| BÀI TẬP TỔNG HỢP
Viết chương trình quản lý Sinh viên Biết mỗi Sinh Viên cần lưu trữ thông tin: Mã sinh viên, họ tên, năm sinh và điểm trung bình Chương trình chính cần xây dựng các chức năng sau:
d Nhập danh sách n sinh viên
e Xuất danh sách sinh viên ra màn hình
f Thêm vào chương trình chức năng xếp loại Sinh viên theo ĐTB đã nhập ở câu trên Biết xếp loại như sau:
g Ghi thông tin sinh viên vào file DSSV.txt
h Đọc từ file DSSV.txt, lọc danh sách những sinh viên có cùng họ
“Nguyen”, ghi thông tin sinh viên tìm được ra file mới có tên KetQua.txt
(Sử dụng kiểu dữ liệu string, struct, file và pointer)
i Thêm vào chương trình chức năng xử lý chuỗi Họ Tên như sau:
Trang 36Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 32
• Xóa bỏ các khoảng trắng đầu và cuối chuỗi
• Xóa bỏ khoảng trắng thừa trong chuỗi
• Chuyển chuỗi thành viết hoa đầu từ
j Thêm vào chương trình chức năng sắp xếp danh sách sinh viên theo thứ tự tăng dần của họ tên rồi lưu kết quả sau khi sắp xếp vào file DSSV_Sort Với danh sách sinh viên được đọc từ file DSSV.txt
(Câu f, g sinh viên cố gắng tự tìm hiểu để mở rộng kiến thức)
Trang 37Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 33
PHÁP LẬP TRÌNH HƯỚNG ĐỐI
TƯỢNG
Chương này nhằm giới thiệu cho sinh viên các khái niệm về phương pháp lập trình Hướng đối tượng, phân biệt phương pháp hướng cấu trúc và hướng đối tượng
Trang 38Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 34
3.1| SO SÁNH LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VÀ LẬP TRÌNH CẤU
Trong lập trình hướng cấu trúc thường quan tâm đến việc phát triển các hàm mà
ít quan tâm tới dữ liệu, điều này khiến cho dữ liệu khó kiểm soát Để liên kết giữa các hàm với nhau, thường dùng biến toàn cục hoặc con trỏ
➢ Ưu điểm của phương pháp lập trình hướng thủ tục:
• Triển khai các phần mềm dễ dàng
• Chương trình dễ hiểu và dễ bảo trì
➢ Nhược điểm của phương pháp lập trình hướng thủ tục:
• Khi có một sự thay đổi dữ liệu phải thực hiện thay đổi ở tất cả hàm liên quan đến dữ liệu đó Đây là công việc tốn thời gian và kém hiệu quả
• Cách tiếp cận đôi khi không phù hợp với thực tế, các diễn đạt thiếu tự nhiên
• Khó mô tả được các hoạt động của thế giới tự nhiên
• Bảo mật kém
Để khắc phục các nhược điểm trên phương pháp lập trình hướng đối tượng ra đời
Lập trình hướng đối tượng (Object Oriented Programming – OOP) là
phương pháp lập trình lấy đối tượng làm nền tảng để xây dựng thuật giải, xây dựng chương trình Thực chất đây không phải là một phương pháp mới mà
là một cách nhìn mới trong việc lập trình
Trong phương pháp lập trình hướng thủ tục, ta thường tư duy theo hướng phân tích một nhiệm vụ lớn thành nhiều công việc nhỏ hơn, sau đó dần dần chi tiết, cụ thể hoá để được các vấn đề đơn giản, để tìm ra cách giải quyết vấn đề dưới dạng những thuật giải cụ thể rõ ràng qua đó dễ dàng minh hoạ bằng ngôn ngữ giải thuật (hay còn gọi các thuật giải này là các chương trình con) Cách thức phân
Trang 39Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 35
tích và thiết kế như vậy chúng ta gọi là nguyên lý lập trình từ trên xuống down), để thể hiện quá trình suy diễn từ cái chung cho đến cái cụ thể
(top-Trong phương pháp lập trình hướng đối tượng thì ta tư duy theo hướng thực hiện thao tác gì với các đối tượng đã có để giải quyết bài toán đặt ra Với cách tư duy này, đối tượng là trung tâm của việc lập trình, người ta gọi là nguyên lý lập trình
từ dưới lên (Bottom-up)
POP (Lập trình hướng thủ tục)
OOP (Lập trình hướng cấu đối
Tập trung vào bảo mật dữ liệu, không phân biệt các thuật toán
Khả năng mở
trình
Rất khó chỉnh sửa, mở rộng khi chương trình có sự thay đổi về dữ liệu Tính tái sử dụng thấp
Dễ dàng chỉnh sửa, mở rộng khi chương trình có sự thay đổi về dữ liệu Tính tái sử dụng cao
Trang 40Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 36
hiện với nhiều kiểu dữ liệu khác nhau, theo nhiều cách khác nhau
Bảng so sánh POP và OOP
3.2| KHÁI NIỆM LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG
Lập trình Hướng đối tượng có tên tiếng Anh là Object-Oriented Programming
Languages, được viết tắt là OOP Đây là một phương pháp lập trình sử dụng các đối tượng (Objects) làm trung tâm để xây dựng chương trình Trong đó người lập trình không chỉ định nghĩa kiểu dữ liệu mà còn định nghĩa các loại phương thức của cấu trúc dữ liệu Nghĩa là ngôn ngữ lập trình cho phép lập trình viên định nghĩa, khởi tạo và thao tác trên các đối tượng
C++ không phải là ngôn ngữ lập trình hướng đối tượng đầu tiên nhưng là một ngôn ngữ được sử dụng rộng rãi trong nhiều ứng dụng
3.3| MỤC TIÊU CỦA LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG
• Tính mạnh mẽ
- Nếu một thư viện có sẵn không phì hợp yêu cầu thì người lập trình có khả năng sửa đổi hoặc mở rộng một cách dễ dàng, không cần phải can thiệp đến mã nguồn thư viện