



















Preview text:
lOMoAR cPSD| 58833082 Một số vấn đề TS. Trần Thanh Hải Đặt vấn đề
• Một số vấn đề thường gặp
• Thực hiện phép chia a/b = ?, nếu b = 0.
• Khi cấp phát động dữ liệu nếu không được thì báo lỗi thế nào?
• Nếu file không mở được thì thông báo thế nào? lOMoAR cPSD| 58833082
• Đối với ma trận:
• Nếu số chiều nhập vào lớn hơn số chiều trong khai báo?
• Nhân 2 ma trận không vuông nếu số cột của ma trận a không
bằng số hàng của ma trận b?
• Đây là những vấn đề ngoại lệ phát sinh ra trong quá trình lập cần
phải được hạn chế và đưa ra cảnh báo đối với người sử dụng
Phân loại các loại ngoại lệ
• Ngoại lệ thứ 1: do người lập trình bắt lỗi với các tình
huống riêng như: chia 0, vượt qua chỉ số mảng,… lOMoAR cPSD| 58833082
• Ngoại lệ thứ 2: do máy bắt lỗi đưa ra: ví dụ cấp phát
động, mở file… thì ta sử dụng trực tiếp lớp ngoại lệ
Xử lý ngoại lệ - try ….catch try{ // try block } catch( type1 arg){ // catch block } . . lOMoAR cPSD| 58833082 catch(typeN arg){ // catch block }
Xử lý ngoại lệ thường sử dụng để kết nối những lỗi rất nặng (chia 0) Ví dụ - try_catch_3.cpp
+ Khi xử lý được đưa ra, điều
khiển được chuyển cho catch, và khối try bị dừng.
+ Chương trình tiếp tục dòng lệnh
int main(){ cout<<"start \n"; trong catch
+ Tuy nhiên khối catch thường kết try{// bat dau khoi lenh
thúc bằng cách gọi exit(), abort().
cout<<"ben trong khoi lenh try \n"; throw 99;// dua ra mot loi
cout<<"Doan nay khong duoc goi \n"; } lOMoAR cPSD| 58833082
catch(int i){ // bat loi cout<<"Bat mot ngoai len -- gia tri i = "; cout<} cout<<"end \n"; }
Sử dụng nhiều câu lệnh catch – try_catch_4.cpp
• Có thể kết hợp một câu lệnh try với nhiều câu lệnh catch() try
{ if(test==0) throw "value is zero"; if(test==1) throw 10; if(test==2) throw 'a'; if(test==3) throw 123.23; }
catch(int i){ cout << "Caught an integer. " << i << endl; }
catch(double i){ cout << "Caught an double. " << i << endl;
} catch (char c) { cout << "Caught an char " << c << endl;
} catch(const char *str) { cout<<"bat mot xau ky tu (test = 0): str = "; cout< lOMoAR cPSD| 58833082 }
catch(...){ // bat toan bo loi neu tren thieu catch cho loai nao thi tat ca chu vao day
cout << "Caught one." << endl; } Rethrowing an exception – try_catch_5.cpp
sử dụng một cảnh báo cho nhiều nơi void XHandler(){ try{ thr ow "hello"; }
catch(const char *) { cout<<"bat throw trong ham \n";
throw; // nem tro lai char * cho ben ngoai ham } } int main() { try{ XHandler(); } lOMoAR cPSD| 58833082
catch(const char * ){ cout<<"bat throw ngoai ham - trong ham main()\n“; } }
Ví dụ về ma trận (ngoại lệ 1)
try { nhapmat(a, row_a, col_a); nhapmat(b, row_b, col_b);
if (col_a!= row_b) { throw 1; }
tichMatran_AB(a,b,c,row_a, col_a); disp(c,row_a,col_b); } catch(int s) {
cout<<"Khong the thuc hien phep nhan tich 2 ma tran \n"; exit(1); } lOMoAR cPSD| 58833082
Ngoại lệ 2: exception - #include
• Tất cả các ngoại lệ được ném (throw) bởi các thành phần của thư
viện chuẩn C ++ exception, dẫn xuất từ lớp exception. exception description bad_alloc
thrown by new on allocation failure bad_cast
thrown by dynamic_cast when it fails in a dynamic cast bad_exception
thrown by certain dynamic exception specifiers bad_typeid thrown by typeid bad_function_call
thrown by empty function objects bad_weak_ptr
thrown by shared_ptr when passed a bad weak_ptr • Thông báo lỗi exception description logic_error
error related to the internal logic of the program lOMoAR cPSD| 58833082 runtime_error error detected during runtime Ví dụ sử dụng // bad_allocstandard exception int* foo; #include foo = new(nothrow) int[5]; if (foo == nullptr) { #include
// error assigning memory. Take measures. using namespace std; } intmain () {
try{ int* myarray= new int[1000]; // bad_alloc }
catch (exception& e){ cout << "Standard exception: " << e.what() << endl; } return 0; }
Ví dụ: try – catch8.cpp lOMoAR cPSD| 58833082
void readFloatFile(const string& fileName, float a[12])
{ ifstream istr; int i = 0; istr.open(fileName.c_str()); if (istr.fail()) {
throw exception(); // nen ra ham main() } while (!istr.eof()) { istr>>a[i]; i = i+1;
} // filename = "E:\\\\tincoso4\\\\side\\\\matran\\\\MATRAN.txt"; }
// hằng ký tự {\\backslash (\)} - ngạch ngang “\\” = \ Ví dụ: try_catch9.cpp lOMoAR cPSD| 58833082
Sử dụng I/O manipulators: include
• Hệ thống I/O của C++ là một cách thứ 2 sử dụng để định dạng
tham số của stream. Đây là phương pháp sử dụng các hàm đặc
biệt, được gọi là manipulator Manipulor Purpose Input/output dec
Format numeric data in decimal Input/output hex
Format numeric data in hexadecimal Input/output oct Format numeric data in octal Input/output setbase(int base) Set the number base to base Output setfill(int ch) Set the fill character to ch Output setioflags(long f)
Turn on the flags specified in f Input/output setprecision(int p)
Set the number of digits of precision Output lOMoAR cPSD| 58833082 setw(int w) Set the fied width to w Output ws Skip leading whitespace Input resetiosflags(long f)
Turn off the flags specified in f Input/output
https://www.includehelp.com/cpp-tutorial/cpp-manipulators-endl-
setwsetprecision-setf-cpp-programming-tutorial.aspx • Manipulator Declaration in endl iostream.h setw iomanip.h setprecision iomanip.h setf iomanip.h Cờ định dạng lOMoAR cPSD| 58833082 •
ios::left , ios::right, ios::internal (-**89) căn phải – dấu bên trái • ios::dec , ios::oct, ios::hex •
ios::fixed , ios::scientific ios::showpos •
ios::uppercase ios::showpoint ios::showbase •
Sử dụng trong các câu lệnh • setiosflags(ios::left) • resetiosflags(long f) include •
setw(int n) // như cout.width(int n) •
setpecision(int n) // như cout.pecision(int n) •
setfill(char ch) // như cout. fill(char ch) lOMoAR cPSD| 58833082 •
setiosflags(long l) // như cout.setf(long f) •
resetiosflags(long l) // như cout.unsetf(long f) • int i = 5; • //cout<phai • cout.width(10); • cout<• cout<• cout<<123<• cout<• cout<•
cout<<123.45<Tạo hàm riêng manipulator • Output function: lOMoAR cPSD| 58833082 •
ostream &manip_name(ostream &stream) { // code here return stream; } •
input manipulator function •
istream &manip_name(istream &stream) { // code here return stream; }
Biến static – từ khóa static
• Biến kiểu static là một biến vĩnh cửu trong hàm riêng hoặc trong file.
• Nó khác biến toàn cục bởi vì nó bên ngoài hàm hoặc file / 203. lOMoAR cPSD| 58833082
• static: tác động lên các biến cục bộ khác
• Biến static cục bộ
• Khai báo : static int count; // giống như const int count = 10;
• static int count = 10; // khởi đầu
• Một biến cục bộ static duy trì giá trị của nó giữa các lần gọi hàm
• Ví dụ: static cục bộ • static toàn cục
Trao đổi – vấn đề
• C++: tạo ra các file .cpp, .h, và .exe.
• .c • Vấn đề: lOMoAR cPSD| 58833082
• Số liệu (hàm, biến) giữa các file có thể liên kết
• Làm thế nào là liên kết giữa các file?
B1. Tạo project – làm việc trên nhiều tệp
• Các bước tạo project lOMoAR cPSD| 58833082 Link: extern (.cpp) lOMoAR cPSD| 58833082
• Từ khóa extern: sử dụng khi một chương trình viết trên nhiều
tệp và các tệp này được dịch độc lập sau đó mới liên kết với nhau
để tạo thành chương trình khả thi (.exe)
• Ví dụ: extern int b_chung;
• Khai báo extern báo cho chương trình dịch biết biến b_chung đã
được định nghĩa ở đâu đó. Do đó, không cần cấp phát bộ nhớ cho nó một lần nữa
• Ví dụ 1: trong trường hợp này trong file: addToprojet9_1.cpp
định nghĩa hàm tích của 2 biến x*y
extern int x, y; // gia trị x, y thay đổi dựa vào hàm main() int func(){ return x*y; }
Vị trí khai báo và phạm vi sử dụng của biến extern lOMoAR cPSD| 58833082 • Ví dụ 2:
• Vị trí khai báo extern: Có thể ngoài các hàm
Có thể bên trong một hàm hoặc một khối lệnh.
• Phạm vi sử dụng của biến extern (nguyên lý): Dù khai báo ở
đâu thì phạm vi sử dụng của biến extern (trên tệp chứa khai báo
này) được tính từ vị trí khai báo cho đến cuối tệp.
• Do đó: Mảng a có thể sử dụng trên toàn tệp
Biến x khai bao trong disp_xExtern(): chỉ sử dụng trong hàm
• TH1: Kết nối biến tổng thể không là hằng: (cpp) //fileA.cpp
//fileB.cpp (file sử dụng) // declaration and definition
// declaration only same as i in FileA int i = 42; extern int i;