Cách khai báo và sử dụng đối tượng dữ liệu, lớp string 3.. • Các đối tượng dữ liệu bên trong một lớp được gọi là các thành phần dữ liệu • Các phép toán cho phép sử dụng trong một lớp đượ
Trang 1NỘI DUNG BÀI 8
Dữ liệu kiểu đối tượng – lớp (class) trong C++
1. Khái niệm lớp và các đặc điểm chung
2. Cách khai báo và sử dụng đối tượng dữ liệu, lớp string
3. Các hàm thành viên trong lớp string thao tác với xâu
(chuỗi) văn bản
Mảng trong C++
1. Khái niệm mảng: cơ chế lưu trữ mảng trong bộ nhớ và
cách truy nhập đến từng phần tử của mảng bằng chỉ mục
2. Sử dụng phép chỉ mục của mảng trong xâu
3. Các phương thức của lớp string dựa trên phép chỉ mục
Trang 2C++ cho phép tạo ra các kiểu dữ liệu phức tạp.
Trong số đó nổi bật là đối tượng dữ liệu Một lớp (class) là
một cách khai báo một đối tượng mà ngữ nghĩa của nó dongười lập trình định nghĩa, chứ không phải do người thiết kếngôn ngữ C++
Trang 3LỚP và ĐỐI TƯỢNG
1 Lớp (class) là cấu trúc dữ liệu phức tạp được tạo bởi các dữliệu cơ bản, và thậm chí bởi các dữ liệu phức tạp khác, cùngvới các phép toán được phép thao tác trên các dữ liệu này
Đó là cách đóng gói các dữ liệu có quan hệ với các phép toán
sử dụng chúng
• Các đối tượng dữ liệu bên trong một lớp được gọi là các
thành phần dữ liệu
• Các phép toán cho phép sử dụng trong một lớp được gọi
là các phương thức hay các hàm thành viên của lớp
2 Đối tượng (object) được sử dụng đồng nghĩa với thuật ngữ lớp
nhưng nó thường được sử dụng rộng rãi hơn, và tinh tế hơntheo nghĩa là bất kỳ dữ liệu thực sự nào của một kiểu hay lớpxác định Ví dụ trong int i, thì i được gọi là đối tượngbởi nó là một sự hoạt động của kiểu int
Trang 4Khai báo và sử dụng đối tượng dữ liệu
• Khai báo định hướng tiền xử lí lớp T
#include < T >
T là tên của heahder file có trong mã nguồn, cho phép truycập các điều kiện và khả năng của các đối tượng lớp T trongmột giao diện chung
• Khai báo đối tượng dữ liệu
T tên trong đó tên là tên đối tượng
• Cách gọi hàm thành viên: dùng toán tử lựa chọn hàm thànhviên . (dấu chấm) Cú pháp truy cập:
tên.hàm_thành_viên(danh_sách_đối_số);
trong đó danh_sách_đối_số là dữ liệu bên trong của đối tượng
tên mà hàm_thành_viên truy cập trực tiếp vào
Trang 5Lớp string (xâu / chuỗi)
Thư viện chuẩn C++ cung cấp đối tượng dữ liệu string đểlưu trữ và thao tác với các xâu kí tự - điều kiện cơ bản để làmviệc với văn bản
Cách tổ chức và sử dụng lớp string
• Khai báo định hướng tiền xử lí
• Khai báo đối tượng dữ liệu:
string tên trong đó tên là tên đối tượng
• Cách gọi hàm thành viên (phương thức) của một đối tượng:
tên.hàm_thành_viên (danh_sách_đối_số) ;
trong đó danh_sách_đối_số là dữ liệu bên trong của đốitượng tên mà hàm_thành_viên của lớp stringtruy cập trực tiếp vào
Trang 6Các hàm cơ bản của lớp string
s.size() Trả lại số ký tự kiểu char trong xâu s
s.append(s2) Ghép xâu s2 vào cuối xâu s
s.push_back(c) Ghép biến ký tự c vào cuối xâu s
s.find(s2) Tìm xâu s2 trong s, trả về vị trí tìm được s.npos Giá trị được s.find trả lại nếu không thấy s2
s < s2 Là true nếu s nhỏ hơn s2
s > s2 Là true nếu s lớn hơn s2
s = = s2 Là true nếu s bằng s2
s <= s2 Là true nếu s nhỏ hơn hoặc bằng s2
s >= s2 Là true nếu s lớn hơn hoặc bằng s2
s ! = s2 Là true nếu s không bằng s2
s + s2 Là xâu mới chứa xâu s ghép với xâu s2
Trang 7Một số ví dụ lưu trữ và thao tác xâu (1)// Làm quen với string
#include <string>
#include <iostream>
using namespace std;
int main() {
string ten; // Khai báo xâu rỗng
string ho_dem("Nguyen Thi "); // Khai báo xâu không rỗng
string nghe = "sinh vien"; // Khai báo và khởi tạo xâu
cout << "Ho ten: "<<ho_dem<<" "<<ten<< ", " << nghe << endl;ten = “Vinh";
cout << "Ho ten: " <<ho_dem<<" "<<ten<<", " << nghe << endl;ho_dem.append(ten); //Ghép xâu
nghe = “giao vien”; // Đổi nội dung (gán xâu)
cout << "Ho ten: "<<ho_dem<< " " << ", " <<nghe << endl;
return 0;
}
Trang 8Một số ví dụ lưu trữ và thao tác xâu (2)
// Tìm xâu con trong xâu cho trước theo mẫu
bool timXauCon(const string &s, const string &mau) {
if (s.npos != s.find(mau)) return true;
else return false;
}
int main() {
string ten(“Vinh"), quan_he, mau;
quan_he = ten; // Gán xâu
quan_he.append(" la sinh vien."); // Ghép xâu
cout << “Co “ << quan_he.size() << " ki tu trong xau ghep "; cout << “Cho xau con can tim “; getline(cin , mau); // Nhập xâu
if (timXauCon(quan_he, mau)) cout << “Tim thay xau con ”
<< mau << “ o chi muc thu “ << s.find ( mau ) << endl;
else cout << “Khong tim thay xau con ” << mau << endl;
return 0;
}
Trang 9Một số ví dụ lưu trữ và thao tác xâu (3)
#include <string> // Lấy ra xâu con trong xâu cho trước
#include <iostream>
using namespace std;
int main() {
string s = "Cong hoa xa hoi chu nghia Viet Nam \n"
"Doc lap - Tu do - Hanh Phuc";string s1, s2;
cout << "Xau s ban dau: \n" << s << endl;
Trang 10MẢNG (array)
Mảng là một cấu trúc dữ liệu của một tập hợp các dữ liệu
có cùng kiểu, có chung tên, các phần tử của mảng đượctham chiếu bởi tên mảng và vị trí (offset hay chỉ mục) củachúng
Chỉ mục của một phần tử trong một mảng là một sốnguyên (bắt đầu từ 0) chỉ ra vị trí của phần tử này kể từđầu mảng
Ngữ nghĩa của mảng: chúng ta có thể đi đến từng phần tửriêng biệt của mảng bằng cách yêu cầu lấy ra một phần tử
ở bất cứ vị trí nào
Trong C++ mảng được lưu trữ trên một vùng bộ nhớ tuần
tự Địa chỉ thấp nhất ứng với phần tử đầu tiên, địa chỉ caonhất ứng với phần tử cuối cùng
Trang 110 1 2 3 4 5 6 7 8 9
• Lớp string trong C++ cung cấp
ngữ nghĩa mảng sử dụng các chỉ mục
từ đầu mảng đến chỉ mục duy nhất,
ấn định cho mỗi kí tự kiểu char
trong một xâu, chỉ mục này là chỉ mục
của từng kí tự riêng biệt
• Ví dụ: xâu str ở trên là một tập các
kí tự, được nhận ra bởi chỉ mục ở đầu
xâu Kí tự đầu tiên 'A' ở vị trí 0 Kí tự
thứ i ở chỉ mục i-1 Kí tự ở chỉ mục 9
là ‘i', và là kí tự thứ mười trong xâu
Ngữ nghĩa mảng với xâu (1)
str[2]thamchiếu tới phần tửthứ ba (kí tự ‘s’)của mảng trong
bộ nhớ tuần tựdành cho xâu
str
Trang 12Sử dụng chỉ mục để thay đổi một kí tự có sẵn trong xâu
#include <iostream>
using namespace std;
int main() {
string s = "Hoan la sinh vien";
s.push_back(' '); // thêm kí tự trống vào cuối xâu s
s.push_back('N'); // thêm kí tự ‘N' vào cuối xâu s
s.push_back(‘1'); // thêm kí tự ‘B' vào cuối xâu s
cout << s << endl;
s[0] = 'T'; // 'T' được đặt vào xâu s ở chỉ mục 0
s.push_back('.'); // thêm kí tự ‘.’ ở cuối xâu s
Trang 13Các phương thức của string với phép chỉ mục
s.erase(i,n) Xóa n kí tự khỏi xâu s, bắt đầu từ chỉ mục i
s.find(s2)
Tìm xâu s2 trong s, trả về chỉ mục của s2
trong s, hoặc s.npos nếu không tìm thấy
(Giá trị mặc định của npos được khởi tạo là giá trị lớn nhất có
thể và được sử dụng với nghĩa „„tất cả các phần tử)s.insert(i, s2) Chèn xâu s2 vào xâu s bắt đầu ở chỉ mục i
s.resize(n) Xác định lại chiều dài của xâu hoặc thêm vào xâu s các kí tự snulllà nkhi cần , bỏ đi
s.size() Trả về số phần tử trong xâu s
s.substr(i, n) Trả về xâu con bao gồm các phần tử của xâu s từ s[i] đến s[i+n]
s.replace(i,n,s2) Thay các kí tự trong xâu tư chỉ mục i đến chỉ mục ns bằng xâu s2, kể
Trang 14Thư viện điều khiển các kí tự (cctype)
int isalnum(char c) Trả về 1 (true) nếu c là một ký tự hay một
số Trái lại, trả về 0 (false)
int isalpha(char c) Trả về 1 (true) nếu c là một chữ Trái lại, trả
về 0 (false)
int isdigit(char c) Trả về 1 (true) nếu c là một số hệ 10 Trái
lại, trả về 0 (false)
int isspace(char c) Trả về 1 (true) nếu c là một khoảng trắng
Trái lại, trả về 0 (false)
int isupper(char c) Trả về 1 (true) nếu c là một ký tự hoa Trái
lại, trả về 0 (false)
int tolower(char c) Đổi kí tự c sang ký tự thường và trả về số
nguyên tương ứng với ký tự đó
int toupper(char c) Đổi kí tự c sang ký tự hoa (nếu c là một ký
tự) và trả về số nguyên tương ứng ký tự đó
Trang 15// CHÈN / XÓA CÁC PHẦN TỬ CỦA XÂU
int main (){
string s, str ( "My name is Vinh" ) ;
// Chèn một xâu vào xâu str từ chỉ mục thứ 11
str.insert ( 11, " Nguyen Thi " ) ;
// Chèn một xâu vào xâu str từ chỉ mục đầu tiên
str.insert ( 0, "Hello " ) ;
// Xóa 8 ký tự đầu của xâu str
str.erase ( 0, 8 ) ;
s = str; // Gán xâu str cho xâu s
// Xóa nửa cuối xâu s
s.erase ( s.size () /2, s.size () /2 + 1 ) ;
// Xóa kí tự thứ ba của xâu s
Trang 16// XÂU CON VÀ MỘT SỐ THAO TÁC
#include <iostream>
using namespace std;
int main() {
string s = "Cong hoa xa hoi chu nghia Viet Nam \n"
"Doc lap - Tu do - Hanh Phuc";string s1, s2;
cout << "Xau ban dau: " << s << endl;
s1 = s.substr(26, 33); // Lấy xâu con từ chỉ mục 26 đến 33
cout << "Xau con tu chi muc 26 den 33: " << s1 << endl;
unsigned viTri = s.find("Doc"); // Tìm vị trí xâu con “Doc”
s2 = s.substr(viTri); // Lấy xâu con từ chỉ mục viTri đến hết
cout << "Xau con tu \"Doc\" den het: " << s2 << endl;
return 0;
} /” Giá trị mặc định của npos được khởi tạo là giá trị lớn nhất
có thể và được sử dụng với nghĩa „„tất cả các phần tử.‟‟ */
Một số ứng dụng của mảng với xâu (2)
Trang 17// ĐỔI XÂU CHỮ THƯỜNG RA XÂU CHỮ HOA
Cách 1: dùng hàm để tạo xâu chữ hoa từ xâu cũ
string upperCase1(string s) {
for(unsigned i = 0; i < s.size(); i ++) s[i] = toupper(s[i]);
return s;
}
Cách 2: tham chiếu đến các xâu dữ liệu được gọi để tạo xâu
void upperCase2(const string & nguon, string & dich) {
dich.resize(nguon.size()); // đặt lại chiều dài của xâu dich
for(unsigned i = 0; i < nguon.size(); i ++)
dich[i] = toupper(nguon[i]); // tạo xâu dich
}
Cách 3: tham chiếu đến xâu đã cho và biến đổi tại chỗ
void upperCase3(string & s) {
for(unsigned i = 0; i < s.size(); i ++) s[i] = toupper(s[i]);
}
Một số ứng dụng của mảng với xâu (3)
Trang 18#include <cassert> // KiỂM TRA XÂU ĐỐI XỨNG
#include <iostream>
using namespace std;
bool doiXung (string s) {
for (int i = 0; i < s.size(); i = i + 1)
if ( s[i] != s[s.size() - 1 - i] ) return false;
return true;
}
int main() {
string a;
cout << "Nhap mot xau:> ";
getline(cin, a); assert(a.size() > 0); // Kiểm tra xâu rỗng?
if ((doiXung(a)) cout << a << " la xau doi xung? “ << endl;
else cout << a << " la xau khong doi xung? " << endl;
return 0;
}
Một số ứng dụng của mảng với xâu (4)
Trang 19Chương trình con và các kiểu chung (1)
Đặt vấn đề: Khi viết nhiều chương trình, chúng ta gặp phải
vấn đề có nhiều hàm giống nhau về cách viết, chỉ có các kiểu
dữ liệu đưa vào là thay đổi Chẳng hạn hàm đổi giá trị của hai biến nguyên
void doiCho(int & x, int & y) {
int trungGian = x;
x = y;
y = trungGian;
}
không dùng được khi x và y có kiểu khác (double, char, bool
hay string) cách khai báo và dùng chung một hàm doiCho
cho nhiều kiểu đối số?
Trang 20Chương trình con và các kiểu chung (2)C++ cung cấp cách viết chương trình con chung, khi đó mã nguồn của nó được tham số hoá bằng các kiểu dữ liệu dự kiến sẽ được thao tác.
Quy cách khai báo
template <class T> kiểu tên_hàm(T tham_số _1,T tham_số _2,…);
Ví dụ: viết lại hàm doiCho dùng chung cho các kiểu dữ liệu
template <class T> void doiCho(T & x, T & y) {
T trungGian = x; // T sẽ được thay bởi kiểu dữ liệu cụ thể khi gọi
x = y;
y = trungGian;
}
Trang 21Chương trình con và các kiểu chung (3)
// Chương trình chính gọi chương trình con có kiểu dữ liệu chung
int main() {
int a = 3, b = 5;
doiCho(a, b); // Đổi giá trị của hai số nguyên
cout << "Sau khi doi cho, so a la " << a
<< " so b la " << b << endl;
double x = 3.15, y = 5.25;
doiCho(x, y); // Đổi giá trị của hai số thực
cout << "Sau khi doi cho, so x la " << x
<< " so y la " << y << endl;
string z = "Cao", t = "Thap";
doiCho(z, t); // Đổi nội dung của hai xâu
cout << "Sau khi doi cho, xau thu nhat la " << z
<< " xau thu hai la " << t << endl;
return 0;
}
Trang 22Bài tập buổi 8