Bài giảng Lập trình hướng đối tượng - Chương 2: Giới thiệu ngôn ngữ C++ - Trần Minh Thái
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình hướng đối tượng - Chương 2: Giới thiệu ngôn ngữ C++ - Trần Minh Thái", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- bai_giang_lap_trinh_huong_doi_tuong_chuong_2_gioi_thieu_ngon.pptx
Nội dung text: Bài giảng Lập trình hướng đối tượng - Chương 2: Giới thiệu ngôn ngữ C++ - Trần Minh Thái
- Chương 2 Giới thiệu ngôn ngữ C++ TRẦN MINH THÁI Email: minhthai@itc.edu.vn Website: www.minhthai.edu.vn Cập nhật: 05 tháng 01 năm 2015
- Nội dung #2 1. Khái niệm cơ bản về ngôn ngữ C++ 2. Một số thay đổi so với ngôn ngữ C 3. Một số bổ sung so với ngôn ngữ C
- Lịch Sử Của C++ #3 C được phát minh trước 1970 bởi Dennis Ritchie Ngôn ngữ cài đặt hệ thống cho hệ điều hành Unix C++ được phát minh bởi Bijarne Stroustroup, bắt đầu năm 1979, dựa trên ngôn ngữ C Các chuẩn ngôn ngữ C++ hiện tại được điều khiển bởi ANSI và ISO
- Đặc điểm C++ #4 C ▪ Đa dụng ▪ Hiệu quả ▪ Gần với ngôn ngữ máy ▪ Khả chuyển Các mở rộng ▪ Tham chiếu ▪ Overloading C++ ▪ Exception handling ▪ Template ▪ OOP ▪ Lớp và đối tượng ▪ Kế thừa ▪ Đa hình ▪
- Cấu trúc chương trình C++ cơ bản #5 Hello.cpp #include int main (void) { cout << "Hello World\n"; } C++ C C++ C Program Code Hello.cpp TRANSLATOR COMPILER C++ C++ Object Program NATIVE Code Hello.obj COMPILER Execut- LINKER able Hello.exe
- Những khác biệt & bổ sung so với C #6 Từ khoá Phạm vi và khai báo Chú thích Không gian tên Kiểu dữ liệu Cấp phát bộ nhớ Kiểm tra kiểu, đổi kiểu Tham chiếu Cảnh báo của trình biên dịch
- Những từ khoá mới #7 asm catch class delete friend inline new operator private protected public template this throw try virtual ➔ Thay đổi định danh trong chương trình C khi chuyển qua C++ nếu trùng với keyword
- Bổ sung chú thích #8 Chú thích một dòng: // Bao ngoài các chú thích một dòng: /* */ /* //This is a variable int x; //This is the variable //being given a value x = 5; */
- Kiểu dữ liệu #9 Bổ sung kiểu Boolean: bool Giá trị: true/ false Các toán tử logic (!, &&, ||), phép toán quan hệ (>, >=, <, <=, !=, ==) → giá trị kiểu bool ➔Các biểu thức điều kiện (if, while, for, do while) đòi hỏi phải là một giá trị kiểu bool
- Kiểu dữ liệu #10 Để tương thích ngược với C, C++ ngầm chuyển từ int sang bool khi cần Giá trị 0 → false Giá trị ≠ 0 → true
- Kiểu dữ liệu #11 Kiểm soát kiểu dữ liệu chặt chẻ hơn C Hàm phải được khai báo trước khi sử dụng Không cho phép gán giá trị nguyên cho các biến kiểu enum ▪ enum Temperature {hot, cold}; ▪ enum Temperature t = 1; //Error in C++ ▪ enum Temperature t = cold; //OK
- Kiểu dữ liệu #12 C++ không cho phép gán trực tiếp con trỏ không kiểu (void *) ▪ void * vp; ▪ int *ip = vp; //Error in C++ ▪ int * ip = (int *) vp; //OK
- Dòng nhập/ xuất chuẩn (Standard I/O stream) #13 Nhập: lấy dữ liệu từ bàn phím, file, Xuất: xuất kết quả lên màn hình, ra file, Sử dụng hai đối tượng (object stream) ▪ cout (console output) ▪ cin (console input)
- Dòng nhập/ xuất chuẩn #14 Sử dụng thư viện thông thường #include void main() { int x, y; cout >x; cout >y; cout<<"Tong cua chung:"<<x+y<<"\n"; cout<<"Hieu cua chung:"<<x-y<<"\n"; }
- Dòng nhập/ xuất chuẩn #15 Sử dụng thư viện theo không gian tên (namespace): C++ trên .Net #include using namespace std; void main() { int x, y; cout >x; cout >y; cout<<"Tong cua chung:"<<x+y<<"\n"; cout<<"Hieu cua chung:"<<x-y<<"\n"; }
- Dòng nhập/ xuất chuẩn #16 cout là một đối tượng được định nghĩa trước trong C++, tương ứng với dòng xuất chuẩn Toán tử << là toán tử chèn, định hướng nội dung cần hiển thị Ví dụ cout<<“Tong cua 2 so:”<<x+y<<endl<<“Hieu cua 2 so:”<<x-y<<endl; !!! endl (end of line)
- Dòng nhập/ xuất chuẩn #17 cin là một đối tượng được định nghĩa trước trong C++, tương ứng với dòng nhập chuẩn Toán tử >> là toán tử trích, đưa nội dung từ dòng nhập chuẩn vào biến Ví dụ cin>>x>>y;
- Xuất có định dạng #18 Thư viện iomanip.h hoặc iomanip (trên .Net) cout<<setw(n)<<tênbiến; → Xuất cách giá trị trước n-1 khoảng trắng Ví dụ: int a=7, b=9; //Xuất giá trị b cách giá trị a 4 khoảng trắng cout<<a<<setw(5)<<b;
- Xuất có định dạng #19 Xuất số thập phân gồm n-1 chữ số lẻ (phần thập phân) cout<<setprecision(n); Ví dụ: Kết quả: float a=7.56745, b=5.339; 7.56745 cout<<a<<endl; 7.57 cout<<setprecision(3)<<a<<endl; 5.3 cout<<setprecision(2)<<b<<endl; 5.339 cout<<setprecision(4)<<b;
- Phạm vi và khai báo #20 Cho phép khai báo biến ở bất kỳ vị trí nào trong chương trình → Giới hạn phạm vi chính xác hơn Bổ sung thêm phạm vi ▪ Phạm vi không gian tên (namespace scope) ▪ Phạm vi lớp (class scope)
- Chuyển kiểu dữ liệu #21 Tự động chuyển kiểu từ kiểu có giá trị thấp thành kiểu có giá trị cao hơn cho phù hợp với phép toan char → short → int → long → float → double Tuy nhiên nếu chuyển ngược lại có thể gây mất dữ liệu → TBD sẽ sinh warning đối với các trường hợp này
- Chuyển kiểu dữ liệu #22 Chuyển kiểu ▪ C: float x = (float) 3/4; ▪ C++: float x = float(3)/4; • Để hạn chế các lỗi, C++ cung cấp một cách mới sử dụng 4 loại chuyển kiểu tường minh: ▪ static_cast ▪ reinterpret_cast ▪ const_cast ▪ dynamic_cast float x = static_cast (3)/4;
- Hằng số (const) #23 C định nghĩa nghĩa hằng bằng tiền xử lý #define, hạn chế: Biên dịch chậm hơn (do trình tiền xử lý tìm và thay thế) Không gắn được kiểu dữ liệu với giá trị hằng Trình debug không biết đến tên hằng
- Hằng số #24 const của ANSI C ít dùng hơn và có ý nghĩa khác: Không dùng để khai báo mảng //Error in C //OK in C++ const int SIZE=100; const int SIZE=100; int a[SIZE]; int a[SIZE];
- Toán tử định phạm vi (scope resolution oprator) #25 Ký hiệu: :: Công dụng: truy xuất đến phần tử bị che khuất bởi phạm vi hiện thời int x=5; void main() { int x=16; cout <<"Bien x toan cuc:"<<x; cout<<"Bien x trong ham main:"<<x; cout<<"Bien x toan cuc:"<<::x; }
- Kiểu có cấu trúc: struct, union, enum #26 Tên truct, union và enum được xem là tên kiểu dữ liệu //C //C++ struct Complex struct Complex { { float r, i; float r, i; }; }; struct Complex c; Complex c; struct và union có thể được xem như lớp
- Bổ sung toán tử new và delete #27 Dùng cấp phát và giải phóng vùng nhớ Cấp phát: toán tử new ▪ new type_name ▪ new ( type_name ) ▪ new type_name initializer ▪ new ( type_name ) initializer Nếu cấp phát không thành công thì sẽ trả về giá trị NULL
- Bổ sung toán tử new và delete #28 Dùng cấp phát và giải phóng vùng nhớ Giải phóng: toán tử delete ▪ delete pointer ▪ delete [] pointer
- Bổ sung toán tử new và delete #29 int *p; p = new int(100); if (p!=NULL) { cout<<*p<<endl; delete p; } else cout<<"Khong con du bo nho de cap phat\n";
- Bổ sung toán tử new và delete #30 int *p; p = new int[10]; if (p!=NULL) { for(int i = 0;i<10;++i) p[i]= i; for(i = 0;i<10;++i) cout<<p[i]<<endl; delete []p; } else cout<<"Khong con du bo nho de cap phat\n";
- Hàm inline #31 Công dụng: chèn code của hàm ngay tại nơi gọi hàm → tăng tốc độ chương trình Thêm từ khoá inline trước hàm
- Hàm inline #32 Hàm inline sẽ làm cho kích thước chương trình tăng lên → Thường là các hàm nhỏ, ít phức tạp (không được là hàm đệ quy) inline float CircleArea(float r) { return (3.14159*r*r); }
- Tham số mặc định (default parameter) #33 Cho phép định giá trị float CircleArea(float r=5); mặc định cho tham số void main() { của hàm x = CircleArea();//r=5 y = CircleArea(7); Gọi hàm với danh sách } đối số không đầy đủ float CircleArea(float r) { (nếu không thay đổi return (3.1415*r*r); } giá trị mặc định)
- Tham số mặc định (default parameter) #34 Lưu ý Các tham số có giá trị mặc định chỉ nằm trong prototype hay trong định nghĩa hàm Một hàm có thể có nhiều tham số mặc định và các tham số này phải nằm cuối cùng trong danh sách tham số của hàm Khi gọi hàm có nhiều tham số mặc định thì có thể bỏ bớt các tham số mặc định từ phải sang trái và phải liên tiếp nhau
- Tham số mặc định (default parameter) #35 int MyFunc(int a= 1, int b , int c = 3, int d = 4); //prototype sai!!! int MyFunc(int a, int b = 2 , int c = 3, int d = 4); //prototype đúng MyFunc(); //Lỗi do tham số a không có giá trị mặc định MyFunc(1); //OK, các tham số b, c và d lấy giá trị mặc định MyFunc(5, 7); //OK, các tham số c và d lấy giá trị mặc định MyFunc(5, 7, , 8); //Lỗi do các tham số bị bỏ phải liên tiếp nhau
- Tham chiếu (reference) #36 Tham chiếu tới một đối tượng là một bí danh tới đối tượng đó Có thể xem mọi thao tác trên tham chiếu đều được thực hiện trên chính đối tượng nguồn Cú pháp: type_name & variable_name
- Tham chiếu (reference) #37 int x = 5; int & y = x; cout << "x = " << x << " y = " << y << ".\n"; //x = 5 y = 5 x = x + 1; cout << "x = " << x << " y = " << y << ".\n"; //x = 6 y = 6 y = y + 1; cout << "x = " << x << " y = " << y << ".\n"; //x = 7 y = 7 int *p = &y; *p = 9; cout << "x = " << x << " y = " << y << ".\n"; //x = 9 y = 9
- Tham chiếu #38 Lưu ý Tham chiếu phải được khởi tạo int & x; //Error Nội dung của tham chiếu là địa chỉ của biến mà nó đại diện (tương tự biến con trỏ)
- Tham chiếu #39 Lưu ý Tham chiếu có thể sử dụng độc lập nhưng thường được dùng: void Swap(int &a, int &b) { ▪ Tham số cho hàm int t = a; a = b; ▪ Giá trị trả về của hàm b = t; } Cho phép các tham số hàm được truyền bằng tham chiếu – tương tự như truyền tham số kiểu con trỏ
- Tham chiếu #40 Lưu ý Tham chiếu hằng không cho phép hàm thay đổi giá trị của tham số được truyền void f(int &a, const int &b) { a = 5; //OK b = 7; //Error }
- Tham chiếu #41 Các hàm có thể trả về một tham chiếu, có thể gọi hàm ở vế trái của một phép gán Khi hàm trả về một tham chiếu tới một biến cục bộ của nó thì biến này phải được khai báo là static int & FindByIndex (int a[], int i) { return a[i]; } FindByIndex(a, i) = 25;
- Đa năng hoá (Overloading) #42 Cho phép đa năng hóa hàm và đa năng hóa toán tử Là phương pháp cung cấp nhiều hơn một định nghĩa cho tên hàm đã cho trong cùng một phạm vi TBD sẽ lựa chọn phiên bản thích hợp của hàm hay toán tử dựa trên các tham số mà nó được gọi
- Đa năng hoá (Overloading) #43 Quá trình gọi hàm đa năng hóa: Nếu tìm thấy một hàm nào đó của một hàm đa năng hóa có các tham số trùng với các tham số trong gọi hàm → hàm đó được sử dụng Nếu không TBD tìm một phiên bản của hàm cho phép chuyển kiểu đơn giản nhất
- Đa năng hoá (Overloading) #44 double max(double d1, double d2) { return (d1 > d2) ? d1 : d2; } int max(int i1, int i2) { return (i1 > i2)? i1 : i2; } void main() { int i = max(12, 8); double d = max(32.9, 17.4); }
- Đa năng hoá #45 Điều kiện Số lượng tham số phải khác nhau Kiểu của tham số phải khác nhau Nếu cùng số lượng tham số thì phải có ít nhất 1 tham số khác kiểu
- Đa năng hoá toán tử (operator overloading) #46 Các toán tử +, - , * , /, chỉ áp dụng đối với các kiểu cài sẵn (int, char, float, ) Muốn dùng các toán tử này trên các kiểu dữ liệu tự định nghĩa thì phải sử dụng đa năng hoá toán tử struct Complex { float r, i; }; Complex c1, c2; Complex c = c1 + c2; Sử dụng cú Đơn giản hóa pháp toán học chương trình
- Đa năng hoá toán tử #47 Một toán tử có thể dùng cho nhiều loại kiểu dữ liệu Các toán tử được chia thành hai loại ▪ Toán tử một ngôi: chỉ có một toán hạng ▪ Toán tử hai ngôi: có hai toán hạng Toán tử một ngôi lại chia thành hai loại ▪ Tiền tố: toán tử đặt trước toán hạng ▪ Hậu tố: toán tử đặt sau toán hạng
- Đa năng hoá toán tử #48
- Đa năng hoá toán tử #49 Cú pháp: type_name operator operator_symbol ( parameters_list ) { } Từ khóa operator khai báo một hàm chỉ rõ ý nghĩa của toán tử operator_symbol.
- Đa năng hoá toán tử #50 Số lượng tham số của hàm chính là số ngôi của toán tử Các toán tử được đa năng hóa sẽ được lựa chọn bởi TBD cũng theo cách thức tương tự như việc chọn lựa giữa các hàm được đa năng hóa
- Đa năng hoá toán tử struct Complex #51 { float r, i; }; Complex operator + (Complex c1, Complex c2) { Complex tmp; tmp.r = c1.r + c2.r; tmp.i = c1.i + c2.i; return tmp; } Complex c1, c2, c; c = c1 + c2; c = operator + (c1, c2);
- Đa năng hoá toán tử #52 Không thể định nghĩa toán tử mới ▪ Phần lớn các toán tử được đa năng hóa ▪ Ngoại trừ các toán tử . .* :: ?: typeid sizeof const_cast dynamic_cast reinterpret_cast static_cast
- Đa năng hoá toán tử #53 Không thể đa năng hóa ký hiệu tiền xử lý Không thể thay đổi độ ưu tiên của toán tử hay số các toán hạng của nó Không thể thay đổi ý nghĩa của toán tử khi áp dụng các kiểu cài sẵn Trong hàm định nghĩa toán tử không có các tham số có giá trị mặc định
- Đa năng hoá toán tử #54 + - * / % | & ^ ~ >> >= = * -> () thành [] new delete thành , gọi hàm viên viên con trỏ + ( type_name ) & * - dấu type_name ( ) địa chỉ con trỏ dấu âm dương Toán tử chuyển kiểu
- Template #55 Được sử dụng khi có những đoạn mã tương đồng về công việc nào đó VD: hàm tìm giá trị lớn nhất của hai số nguyên int Max(int a, int b) { return (a>b) ? a : b; } Hàm này chỉ sử dụng cho 2 số nguyên, đối với số thực → viết lại hàm có sự thay đổi về kiểu dữ liệu
- Template #56 Template để giải quyết vấn đề xử lý có tính chất tổng quát (genetic) với kiểu dữ liệu chưa xác định Dựa vào template có thể tạo các công việc cụ thể (thực thể) theo một cách nào đó Gồm 2 loại ▪ Hàm template ▪ Lớp template
- Hàm template #57 Hàm đặc biệt được tham số sao cho chúng thể hiện một họ các hàm Cung cấp một hàm mà có thể được gọi cho các kiểu dữ liệu khác nhau Hàm template có thể có một hoặc nhiều tham số hình thức gọi là tham số kiểu
- Hàm template #58 Cú pháp: ▪ Định nghĩa template function_declaration template function_declaration ▪ Sử dụng function_name ( parameters ); function_name ( parameters );
- Hàm template #59 Tham số kiểu template T Max(T a, T b) { return (a>b) ? a : b; } void main() { int x = 4, y = 12; cout (x,y)<<endl; // int Max(int, int) float u = 2.5, v = 1.25; cout<<"Max(u,v)="<<Max(u,v)<<endl; // float Max(float, float) } TBD sản sinh ra hàm thực thể
- Hàm template #60 template void MyFun(T x) { cout void MyFun(T1 x,T2 y) { cout<<x<<y<<endl; } void MyFun(int x,int y, int z) { cout<<x<<y<<z<<endl; }
- Hàm template #61 Tham số kiểu Tham số biểu thức template int ZeroCount(T x[]) { int count=0; for(int i=0;i (a); }
- Q&A #62