You are on page 1of 31

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?
• Đố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,…
• 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ệ
<exception>
Xử lý ngoại lệ - try ….catch

try{
// try block
}
catch( type1 arg){
// catch block
}
.
.
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)
+ Khi xử lý được đưa ra, điều
Ví dụ - try_catch_3.cpp 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 trong catch
int main(){ + Tuy nhiên khối catch thường
cout<<"start \n"; kết thúc bằng cách gọi exit(),
try{// bat dau khoi lenh abort().
cout<<"ben trong khoi lenh try \n";
throw 99;// dua ra mot loi
cout<<"Doan nay khong duoc goi \n";
}
catch(int i){ // bat loi
cout<<"Bat mot ngoai len -- gia tri i = ";
cout<<i<<"\n";
}
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<<str<<endl;
}
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{
throw "hello";
}
catch(const char *) {
cout<<"bat throw trong ham \n";
throw; // nem tro lai char * cho ben ngoai ham
}
}
int main()
{
try{
XHandler();
}
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);
}
Ngoại lệ 2: exception - #include <exception>
• 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
runtime_error error detected during runtime
Ví dụ sử dụng <exception>

// bad_alloc standard exception int * foo;


foo = new (nothrow) int [5];
#include <iostream>
if (foo == nullptr) {
#include <exception> // error assigning memory. Take measures.
using namespace std; }

int main () {
try{
int* myarray= new int[1000]; // bad_alloc
}
catch (exception& e){
cout << "Standard exception: " << e.what() << endl;
}
return 0;
}
Ví dụ: try – catch8.cpp

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
Sử dụng I/O manipulators: include <iomanip>
• 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


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-setw-
setprecision-setf-cpp-programming-tutorial.aspx

• Manipulator Declaration in
endl iostream.h
setw iomanip.h
setprecision iomanip.h
setf iomanip.h
Cờ định dạng

• 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<iomanip>

• setw(int n) // như cout.width(int n)


• setpecision(int n) // như cout.pecision(int n)
• setfill(char ch) // như cout. fill(char ch)
• setiosflags(long l) // như cout.setf(long f)
• resetiosflags(long l) // như cout.unsetf(long f)
• int i = 5;
• //cout<<setw(10)<<i<<endl; // dat do rong cua so la 10, can phai
• cout.width(10);
• cout<<i<<endl;
• cout<<setiosflags(ios::left); // can tai
• cout<<123<<endl;
• cout<<setiosflags(ios::scientific); // dang khoa hoc e
• cout<<setprecision(2);
• cout<<123.45<<endl;
Tạo hàm riêng manipulator

• Output function:
• 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.
• 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 đề:
• 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
Link: extern (.cpp)

• 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

• 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;

• TH2: Kết nối biến tổng thể là hằng (const): (cpp)


//fileA.cpp //fileB.cpp (file sử dụng)
// declaration and definition // declaration only same as i in FileA
extern const int i = 42; extern const int i = 42;

• TH3: (.c) // header files to have C linkage.


extern "C" {
// add your #include statements here
#include <stdio.h> }
• https://docs.microsoft.com/en-us/cpp/cpp/extern-
cpp?view=msvc-170
• Ví dụ 2:
Link: Tạo tệp .h (header file #include” “)

• Bước 1: tạo project.


• Bước 2: tạo mới một file (.h) như hình và chọn New File. Sau
đó save và lựa chọn phần mở rộng là (.h)
• Thêm một tệp file .h sẵn có : như hình chọn add to Project
Tổ chức các tệp thư viên
• Một phương pháp dịch có điều kiện khác là sử dụng chỉ thị
biên dịch có điều kiện ifdef và ifndef (nếu đã định nghĩa) và
nếu chưa định nghĩa.
• Cấu trúc tệp defs.h
ifndef _DEFS_H_
define _DEFS_H_
// nội dung cần thục hiện
endif
• Như vậy, có thể thấy rằng mặc dù tệp defs.h được chèn vào
tệp nguồn tại nhiều chỗ, nhưng nó chỉ biên dịch khi gặp lần
đầu (lúc _DEFS_H_ còn chưa được xác định). Các phiên bản
sau của defs.h đều bị bỏ qua (vì _DEFS_H_ đã được định
nghĩa trong lần đầu gặp tệp defs.h). Do đó, rất thuận lợi trong
trường hợp ta viết gộp nhiều tệp.
Preprocessor directives: tiền chỉ thị

• #define identifier replacement


• Conditional inclusions (#ifdef, #ifndef, #if, #endif, #else and
#elif)
• Line control (#line)
• Error directive (#error)
• Source file inclusion (#include)
• Pragma directive (#pragma)
• Predefined macro names
• Thông tin:
• https://www.cplusplus.com/doc/tutorial/preprocessor/
Link 3: (.exe) Ví dụ

• Xem ví dụ
• Hướng dẫn tạo file.
• Cách sử dụng
• Cách gọi hàm.

• #include<windows.h>
• char program[] = "Notepad.exe MATRAN.txt";
• WinExec(program, SW_SHOWNORMAL);
char program[] = "C:\\Program Files\\Microsoft
Office\\Office16\\EXCEL.EXE a2.csv";
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-winexec
Value Meaning
SW_HIDE Hides the window and activates another window.
0
SW_SHOWNORMAL Activates and displays a window. If the window is minimized or
SW_NORMAL maximized, the system restores it to its original size and position.
1 An application should specify this flag when displaying the window
for the first time.
SW_SHOWMINIMIZED Activates the window and displays it as a minimized window.
2
SW_SHOWMAXIMIZED Activates the window and displays it as a maximized window.
SW_MAXIMIZE
3
SW_SHOWNOACTIVATE Displays a window in its most recent size and position. This value is
4 similar to SW_SHOWNORMAL, except that the window is not
activated.
SW_SHOW Activates the window and displays it in its current size and position.
5
SW_MINIMIZE Minimizes the specified window and activates the next top-level
6 window in the Z order.
SW_SHOWMINNOACTIVE Displays the window as a minimized window. This value is similar
7 to SW_SHOWMINIMIZED, except the window is not activated.
SW_SHOWNA Displays the window in its current size and position. This value is
8 similar to SW_SHOW, except that the window is not activated.
SW_RESTORE Activates and displays the window. If the window is minimized or
9 maximized, the system restores it to its original size and position.
An application should specify this flag when restoring a minimized
window.
SW_SHOWDEFAULT Sets the show state based on the SW_ value specified in
10 the STARTUPINFO structure passed to the CreateProcess function
by the program that started the application.
SW_FORCEMINIMIZE Minimizes a window, even if the thread that owns the window is
11 not responding. This flag should only be used when minimizing
windows from a different thread.
Ứng dụng sử dụng lệnh: system

• Chương trình tắt máy tính (win7)


• Chương trình lấy địa chỉ IP của máy
• #include <bits/stdc++.h>: Thay cho tất cả các thư
viện
Hàm thời gian: Time
#include<ctime>
using std::cout; using std::endl;
int main() {
time_t now = time(0); // get time now (Thu + Nam + ngay, gio + phu + giay, nam)
char *dt = ctime(&now);
cout<<"The local date and time is "<<dt<<"\n";
// Lay tung tham so cua ngay thang nam, gio phu giay
struct tm *t = localtime(&now);

cout<<"The local day is: "<<t->tm_mday<<"\n";


cout<<"The current month is: "<<t->tm_mon<<"\n";
cout<<"The current year is: "<<(t->tm_year + 1900)<<"\n";
cout<<"Display the date of day is: "<<t->tm_mday<<"-"<<t->tm_mon<<"-"<<(t-
>tm_year+1900)<<endl;

cout<<"The current hour is: "<<t->tm_hour <<"\n";


cout<<"The current minute is: "<<t->tm_min<<"\n";
cout<<"The current second is: "<<t->tm_sec<<"\n";
cout<<"Display hour:minute:second is: "<<t->tm_hour<<":"<<t->tm_min<<":"<<t-
>tm_sec<<endl; }
Tính thời gian chạy một đoạn code

• https://www.tutorialspoint.com/c_standard_library/c_function_clock.htm

• Tính thời gian của một đoạn chương trình (cả thời
gian chờ) #include<time.h>
• start_t = clock();
-----
-----
-----
• end_t = clock();
• total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
(second)

You might also like