Toàn bộ kiến thức cơ bản về C++ – Nguyễn Công Trình tổng hợp
Nội Dung Chính
Tổng quan về C++
C++ là một ngôn ngữ lập trình kiểu tĩnh,dữ liệu trừ tượng, phân biệt kiểu chữ thường chữ hoa mà hỗ trợ lập trình hướng đối tượng, lập trình thủ tục.
C++ được coi như là ngôn ngữ bậc trung (middle-level), khi nó kết hợp các đặc điểm và tính năng của ngôn ngữ bậc cao và bậc thấp.
C++ được phát triển bởi Bjarne Stroustrup năm 1979 tại Bell Labs ở Murray Hill, New Jersey, như là một bản nâng cao của ngôn ngữ C và với tên gọi đầu tiên là « C với các Lớp », nhưng sau đó được đổi tên thành C++ vào năm 1983.
C++ là một Superset của C, và bất kỳ chương trình C nào cũng là một chương trình C++.
Cấu trúc một chương trình trong C++
1. Statements
Khai báo tên các tệp chứa những thành phần có sẵn ( các hằng chuẩn, kiểu chuẩn và hàm chuẩn) mà người sử dụng sẽ sử dụng trong chương trình.
Ví dụ:
int x;
x = 5;
std::cout << x;
2. Expressions
Trình biên dịch cũng có khả năng giải quyết các biểu thức. Biểu thức xác định một tính toán sẽ được thực hiện.
Ví dụ, tất cả chúng ta đều học rằng 2 + 3 bằng 5. Trong lập trình, chúng ta nói rằng 2 + 3 là một biểu thức đánh giá giá trị 5
Ví dụ:
2
« Hello, world »
x
2 + 3
x = 5
(2+x)*(y-3)
std::cout << x
3. Functions
Trong C ++, các câu lệnh thường được nhóm thành các đơn vị gọi là hàm. Hàm là một tập hợp các câu lệnh thực thi tuần tự. Mỗi chương trình C ++ phải chứa một hàm đặc biệt gọi là main.Các chức năng thường được viết để làm một công việc rất cụ thể.
Ví dụ:
int main()
{
int a;
cin >> a;
if (a <4){
cout << « so nho hon 4″<< endl;
} else{
cout << « so lon hon 4″<< endl;
}
system(« pause »);
return 0;
}
Các kiểu dữ liệu trong C++
Ví dụ:
#include
using namespace std;
int main()
{
cout << « Kich thuoc cua char la: » << sizeof(char)<< endl;
cout << « Kich thuoc cua int la: » << sizeof(int)<< endl;
cout << « Kich thuoc cua short int la: » << sizeof(short int)<< endl;
cout << « Kich thuoc cua long int la: » << sizeof(int)<< endl;
cout << « Kich thuoc cua float la: » << sizeof(float)<< endl;
cout << « Kich thuoc cua double la: » << sizeof(double)<< endl;
cout << « Kich thuoc cua wchar_t la: » << sizeof(wchar_t)<< endl;
system(« pause »);
return 0;
}
Biến trong C++
Trong C++, biến có thể được khai báo ở bất kì địa điểm nào trong chương trình trước khi sử dụng.
-
Tên của một biến :
- Bắt đầu bằng dấu gạch dưới “_” hoặc chữ cái.Tên biến có thể là chữ hoa hoặc chữ thường như là a-z hoặc A-Z. Trong C phân biệt chữ hoa chữ thường.
- Tên biến có thể bao gồm chữ cái, chữ số, và dấu gạch dưới.
- Không bao gồm các kĩ tự đặc biệt như là !, %, ], $.
- Không bao gồm khoảng trống.
- Không được trùng tên với từ khóa.
- Không nên dài quá 32 kí tự.
-
Cách khai báo biến
- Khai báo không khởi tạo
Tên_kiểu Tên_biến;
Ví dụ:
int i, j; // khai báo 2 biên i, j kiểu nguyên
float x; // khai báo biến x kiểu float.
char c,d[100]; // biến kí tự c, xâu d chứa tối đa 100 kí tự.
- Khai báo khởi tạo
Tên_kiểu Tên_biến = Giá_trị;
Ví dụ:
int a = 5;
float b = 6.5;
string st = « nhom 1 »;
Con trỏ trong C++
- Khai báo:
Kiểu_dữ_liệu *tên_con_trỏ
Ví dụ:
int *iPtr; float *fPtr; double *dPtr; int *iPtr1, *iPtr2;
Lưu ý: Dấu sao trong khai báo con trỏ không phải là toán tử trỏ đến (dereference operator), nó chỉ là cú pháp được ngôn ngữ C/C++ quy định.
Cách khai báo dễ gây nhầm lẫn
Ngôn ngữ C/C++ yêu cầu đặt dấu sao giữa kiểu dữ liệu và tên con trỏ nhưng không bắt buộc phải đặt nó gần với kiểu dữ liệu hay gần với tên con trỏ. Do đó, những cách khai báo dưới đây đều được cho phép:
int *iPtr1; //We recommended you use this way to declare pointers int* iPtr2;
Nhưng mình khuyến nghị các bạn sử dụng cách khai báo đặt dấu sao ngay trước tên con trỏ vì cách thứ hai có thể gây nhầm lẫn.
int* iPtr1, iPtr2;
Với cách khai báo này, iPtr1 là một con trỏ kiểu int, trong khi đó, iPtr2 là một biến kiểu int. Để có được hai con trỏ, chúng ta cần khai báo như sau:
int *iPtr1, *iPtr2;
-
Gán giá trị cho con trỏ
Giá trị mà biến con trỏ lưu trữ là địa chỉ của biến khác có cùng kiểu dữ liệu với biến con trỏ.
int *ptr;
int value = 5;
ptr = &value;
Do đó, chúng ta cần sử dụng address-of operator để lấy ra địa chỉ ảo của biến rồi mới gán cho con trỏ được. Lúc này, biến ptr sẽ lưu trữ địa chỉ ảo của biến value.
Chúng ta có thể nói rằng con trỏ ptr đang nắm giữ địa chỉ của biến value, cũng có thể nói con trỏ ptr trỏ đến biến value.
Đoạn chương trình sau sẽ in ra địa chỉ của biến value và giá trị được lưu bởi con trỏ ptr sau khi trỏ đến biến value:
int main() {
int value = 5;
int *ptr = &value;
cout << &value << endl; cout << ptr << endl;
system(« pause »);
return 0;
}
- Kết quả : 0012FF7C
0012FF7C
Lý do mà chúng ta gán được địa chỉ của biến value cho con trỏ kiểu int (int *) là vì address-of operator của một biến kiểu int trả về giá trị kiểu con trỏ kiểu int (int *).
Bên cạnh đó, khi có hai con trỏ cùng kiểu thì chúng ta có thể gán trực tiếp mà không cần sử dụng address-of operator.
Ví dụ:
int main() {
int value = 5;
int *ptr1, *ptr2; ptr1 = &value; //ptr1 point to value
ptr2 = ptr1; //assign value of ptr1 to ptr2
cout << ptr1 << endl; cout << ptr2 << endl;
system(« pause »);
return 0;
}
Lúc này, ptr1 và ptr2 cùng giữ địa chỉ của biến value.
Khác với tham chiếu (reference), một con trỏ có thể trỏ đến địa chỉ khác trong bộ nhớ ảo sau khi đã được gán giá trị. Tham chiếu (reference) không thể thay đổi địa chỉ sau lần tham chiếu đầu tiên.
Ví dụ:
int main() {
int *ptr;
int arr[5] = { 1, 2, 3, 4, 5 };
for(int i = 0; i < 5; i++) {
ptr = &arr[i]; cout << ptr << endl;
}
system(« pause »);
return 0;
}
-
Các phép gán không hợp lệ khi sử dụng con trỏ
Phép gán của con trỏ chỉ thực hiện được khi kiểu dữ liệu của con trỏ phù hợp kiểu dữ liệu của biến mà nó sẽ trỏ tới.
int iValue = 0;
float fValue = 0.0;
int *i_ptr = fValue; //wrong! int pointer cannot point to the address of a double variable
float *f_ptr = iValue; //wrong! float pointer cannot point to the address of an int variable
Mặc dù giá trị mà con trỏ lưu trữ có kiểu unsigned int, nhưng chúng ta không thể gán trực tiếp một giá trị địa chỉ cho con trỏ được.
int *ptr = 1245052; //wrong!
Giá trị 1245052 không có địa chỉ cụ thể, trong khi đó, con trỏ chỉ nhận giá trị là địa chỉ nên phép gán trên là sai. Mặc dù giá trị được chuyển về dạng cơ số thập lục phân để tương xứng với định dạng giá trị mà con trỏ in ra, điều này cũng không được cho phép.
int *ptr = 0012FF7C; //wrong!
Chỉ có giá trị kiểu con trỏ (có được nhờ toán tử address-of, hoặc từ một biến con trỏ cùng kiểu khác) mới có thể gán được cho biến con trỏ.
-
Truy xuất giá trị bên trong vùng nhớ mà con trỏ trỏ đến
Khi chúng ta có một con trỏ đã được trỏ đến địa chỉ nào đó trong bộ nhớ ảo, chúng ta có thể truy xuất giá trị tại địa chỉ đó bằng dereference operator. Dereference operator sẽ đánh giá nội dung địa chỉ được trỏ đến.
Ví dụ:
int *ptr; //declare an int pointer
int value = 5;
ptr = &value; //ptr point to value
cout << &value << endl; //print the address of value
cout << ptr << endl; //print the address of value which is held in ptr
cout << value << endl; //print the content of value
cout << *(&value) << endl; //print the content of value
cout << *ptr << endl; //print the content of value
Đối với con trỏ, NULL là một giá trị đặc biệt, khi gán NULL cho con trỏ, điều đó có nghĩa là con trỏ đó chưa trỏ đến địa chỉ nào cả. Con trỏ đang giữ giá trị NULL được gọi là con trỏ NULL (NULL pointer).
int *ptr = NULL; //ptr is now a NULL pointer
Struct, mảng trong C++
structure – cấu trúc là một loại dữ liệu khác trong ngôn ngữ lập trình C/C++, cho phép bạn kết hợp các dữ liệu khác kiểu nhau.
Để định nghĩa cấu trúc, bạn phải sử dụng câu lệnh struct. Câu lệnh struct định nghĩa một kiểu dữ liệu mới, với hơn một thành viên trong chương trình của bạn. Dạng tổng quát của câu lệnh struct như sau đây:
struct [ten cau truc]
{
phan dinh nghia thanh vien;
phan dinh nghia thanh vien;
…
phan dinh nghia thanh vien;
} [mot hoac nhieu bien cau truc];
Ví dụ:
struct Books
{
char tieude[50];
char tacgia[50];
char chude[100];
int book_id;
}book;
-
Truy cập các thành viên của cấu trúc trong C++
Để truy cập bất kỳ thành viên nào của cấu trúc, bạn sử dụng toán tử truy cập phần tử (.). Toán tử truy cập thành viên cấu trúc được mã hóa là dấu chấm giữa tên biến cấu trúc và thành viên cấu trúc mà bạn muốn truy cập. Bạn sẽ sử dụng từ khóa struct để định nghĩa các biến của kiểu cấu trúc. Dưới đây là ví dụ cho cách sử dụng cấu trúc trong C++:
#include
#include
using namespace std;
struct Books
{
char tieude[50];
char tacgia[50];
char chude[100];
int book_id;
};
int main( )
{
struct Books QuyenSach1; // Declare QuyenSach1 of type Book
struct Books QuyenSach2; // Declare QuyenSach2 of type Book
// chi tiet ve quyen sach thu nhat
strcpy( QuyenSach1.tieude, « Ngon ngu Lap trinh C++ »);
strcpy( QuyenSach1.tacgia, « Pham Van At »);
strcpy( QuyenSach1.chude, « Lap trinh »);
QuyenSach1.book_id = 1225;
// in thong tin ve QuyenSach1
cout << « Tieu de cua Quyen sach thu nhat la: » << QuyenSach1.tieude <<endl;
cout << « Tac gia cua Quyen sach thu nhat la: » << QuyenSach1.tacgia <<endl;
cout << « Chu de cua Quyen sach thu nhat la: » << QuyenSach1.chude <<endl;
cout << « ID cua Quyen sach thu nhat la: » << QuyenSach1.book_id <<endl;
return 0;
}
- Mảng
Mảng gồm 2 loại: Mảng tĩnh và Mảng động
- Mảng tĩnh
Mảng một chiều:
- Là một dãy các ô nhớ liên tục nhau đánh số từ 0 -> n – 1 (với n là số lượng các phần tử).
- Kích thước được xác định ngay khi khai báo và không bao giờ thay đổi.
- Cách khai báo mảng:
Phải xác định cụ thể số phần tử ngay lúc khai báo.
int n1=10;
int a [n1];
Const int n2 =20; int b[n2];
Nên sử dụng chỉ thị tiền xử lí #define để định nghĩa về số phần tử của mảng.
#define n1 10
#define n2 20
int a [n1]; ó int a[10]; // mảng 1 chiều
int b [n1][n2]; ó int b[10][20]; // mảng 2 chiều
Khởi tạo giá trị cho mảng.
- Khởi tạo giá trị cho mọi phần tử của mảng.
int a[4] = {1012,1032,2012,1034};
- Khởi tạo giá trị cho một số phần tử đầu mảng
int a[4] = {2012,1023};
- Khởi tạo giá trị 0 cho mọi phần tử mảng.
int a[4] = {0};
- Tự động xác định số phần tử mảng.
int a[] = {1012,1032,2012,1034};
- Mảng động
Biến con trỏ dùng để lưu địa chỉ của những biến khác hay địa chỉ của một vùng nhớ hợp lệ, được phép dùng.
Cần dùng bao nhiêu thì cấp bấy nhiêu không cấp dư.
int *p;
int a =5;
p =&a;
*p=15;
//a=15
}
{
int *p;
p=new int;
*p=8;
delete p;
}
Các câu lệnh điều kiện, vòng lặp trong C++
- Câu lệnh điều kiện.
- Câu lệnh điều kiện if
- Cấu trúc câu lệnh if thiếu
If ( điều kiện)
{
Thân của if gồm lệnh hoặc khối lệnh
}
- Cấu trúc câu lệnh if đủ
If ( điều kiện)
{
Thân của if gồm lệnh hoặc khối lệnh
}
Else
{
Khối lệnh}
Ví dụ:
#include
using namespace std;
int main()
{
int a;
cin >> a;
if (a >4){
cout << « so nho hon 4″<< endl;}
else{
cout << « so lon hon 4″<< endl;}
system(« pause »);
return 0;
}
-
Câu lệnh điều kiện Swicth-case
Cấu trúc:
Switch ( giá trị hay biểu thức)
{
Case1:{ lựa chọn 1
}break;
Case1:{ lựa chọn 1
}break;
}
Default:
{cout << “….” << endl;
}}
Ví dụ:
#include
using namespace std;
int main()
{
int luachon;
cout << « nhap lua chon cua ban »; cin >> luachon;
switch(luachon)
{
case 1: {
cout << « ban chon so 1 »;
break;
}
case 2: {
cout << « ban chon so 2 »;
break;
}
}
system (« pause »);
return 0;
}
- Vòng lặp.
Trong C++ có ba vòng lặp chính : While, Do –While, for.
- Vòng lặp While
Cú pháp:
While (Biểu thức logic)
{ thân vòng lặp while (lệnh hoặc đoạn lệnh)
}
Ví dụ:
#include
using namespace std;
//viet1 chuong trinh in ra cac so tu 0-100
int main()
{
int a =0;
while(a<=100){
cout << a << endl;
a++;
}
system (« pause »);
return 0;
}
===========
+Kênh youtube chính của tớ : https://www.youtube.com/channel/UCmh5eroSubN_w1J4u19d6_Q
+facebook cá nhân :https://www.facebook.com/NguyenCongTrinh113
===========
-
Vòng lặp Do- While
Cú pháp:
Do
{ lệnh, khối lệnh
} while( biểu thức logic- điều kiện vòng lặp);
Ví dụ:
#include
using namespace std;
// viet chuong trinh nhap vao so nguyen n, voi n>0;
int main()
{
int n;// khai bao bien n
do {
cout << « nhap n »<< endl; cin >> n;
}while(n<=0);
{
cout << « gia tri n la: »<< n<< endl;
}
system (« pause »);
return 0;
}
-
Vòng lặp for
Cú pháp:
For (< giá trị khởi tạo> ; <điều kiện lặp>; <bước lặp >)
{ lệnh, đoạn lệnh
}
Ví dụ:
#include
using namespace std;
//
int main(){
int i,n;
cout <<« nhap vao gia tri n »<< endl; cin >> n;
for(i=0;i<n;i++){
cout << « gia tri n la: »<< i<< endl;
}
system (« pause »);
return 0;
}
Lập trình hướng đối tượng trong C++
Đối tượng và các lớp trong C++
Object (đối tượng) nghĩa là một thực thể trong thế giới thực, chẳng hạn như: bàn, quả bóng, con bò, … Lập trình hướng đối tượng là một phương pháp để thiết kế một chương trình bởi sử dụng các lớp và các đối tượng. Nó làm đơn giản hóa việc duy trì và phát triển phần mềm bằng việc cung cấp một số khái niệm.
Về cơ bản, một đối tượng (objects) được tạo từ một lớp.
Khai báo các đối tượng của một lớp giống đúng như chúng ta khai báo các biến của kiểu cơ bản.
- 4 tính chất của đối tượng:
- Tính trừu tượng (Abstraction)
- Tính đóng gói (Escapsulation)
- Tính kế thừa (Inheritance)
- Tính đa hình (polymorphism)
- Tính trừu tượng (Abstraction): Tập trung vào cốt lõi của đối tượng, bỏ qua những thứ không lien quan và không quan trọng. Bao hàm các điểm chung để xâu ra bên ngoài.
- Tính đóng gói (Escapsulation): Tính chất không cho phép người dung hay đối tượng khác thay đổi dữ liệu thành viên của đối tượng nội tại, chỉ có các hàm thành viên của đối tượng đó mới có quyền thay đổi trạng thái nội tại của nó, truy cập thông tin qua phương thức get/set.
- Đặc điểm của tính chất đóng gói dữ liệu:
- Tạo ra các cơ chế để ngăn ngừa về việc gọi phương thức của lớp này tác động truy xuất dữ liệu của lớp đối tượng thuộc về lớp khác.
- Người lập trình có thể dựa vào cơ chế này để ngăn ngừa việc gán giá trị không hợp lệ vào thành phần dữ liệu của mỗi đối tượng.
- Không cho truy xuất 1 cách tùy tiện dữ liệu của class nôi tại.
- Tính kế thừa (Inheritance)
Kế thừa , tái sử dụng phương thức, thuộc tính của lớp cơ sở.
Lớp kế thừa được gọi là lớp con, nó sẽ thừa hưởng những gì lớp cha có và cho phép.
- Tính đa hình (polymorphism)
Tính đa hình cho phép các chức năng (method) khác nhau được thực thi khác nhau trên các đối tượng khác nhau. Hay nói cách khác đa hình là cùng phương thức khác nhau về hình thể.
- Lớp C++
Một định nghĩa lớp trong C++ bắt đầu với từ khóa class, được theo sau bởi tên lớp và phần thân lớp, được bao quanh trong một cặp dấu ngoặc móc. Một định nghĩa lớp phải được theo sau: hoặc bởi một dấu chấm phảy hoặc một danh sách các khai báo.
Ví dụ, chúng ta định nghĩa kiểu dữ liệu SinhVien bởi sử dụng từ khóa class trong C++ như sau:
class SinhVien
{
private:
string hoten;
string masv;
float diem;
public:
void Nhap_thong_tin();
void Xuat_thong_tin();
protected:
string email;
}
Từ khóa public quyết định các thuộc tính truy cập của các thành viên lớp mà theo sau nó. Một thành viên public có thể được truy cập từ bên ngoài lớp bất cứ đâu bên trong phạm vi (scope) của đối tượng lớp đó.
- Tạo ra các cơ chế để ngăn ngừa về việc gọi phương thức của lớp này tác động truy xuất dữ liệu của lớp đối tượng thuộc về lớp khác.
- Người lập trình có thể dựa vào cơ chế này để ngăn ngừa việc gán giá trị không hợp lệ vào thành phần dữ liệu của mỗi đối tượng.
- Không cho truy xuất 1 cách tùy tiện dữ liệu của class nôi tại.
-
Tính kế thừa (Inheritance)
Kế thừa , tái sử dụng phương thức, thuộc tính của lớp cơ sở.
Lớp kế thừa được gọi là lớp con, nó sẽ thừa hưởng những gì lớp cha có và cho phép.
-
Tính đa hình (polymorphism)
Tính đa hình cho phép các chức năng (method) khác nhau được thực thi khác nhau trên các đối tượng khác nhau. Hay nói cách khác đa hình là cùng phương thức khác nhau về hình thể.
Lớp C++
Một định nghĩa lớp trong C++ bắt đầu với từ khóa class, được theo sau bởi tên lớp và phần thân lớp, được bao quanh trong một cặp dấu ngoặc móc. Một định nghĩa lớp phải được theo sau: hoặc bởi một dấu chấm phảy hoặc một danh sách các khai báo.
Ví dụ, chúng ta định nghĩa kiểu dữ liệu SinhVien bởi sử dụng từ khóa class trong C++ như sau:
class SinhVien
{
private:
string hoten;
string masv;
float diem;
public:
void Nhap_thong_tin();
void Xuat_thong_tin();
protected:
string email;
}
Từ khóa public quyết định các thuộc tính truy cập của các thành viên lớp mà theo sau nó. Một thành viên public có thể được truy cập từ bên ngoài lớp bất cứ đâu bên trong phạm vi (scope) của đối tượng lớp đó.
Từ khóa private và protected thể hiện tính đóng gói trong C++.
Các thành viên dữ liệu public của các đối tượng của một lớp có thể được truy cập bởi sử dụng toán tử truy cập thành viên trực tiếp là dấu chấm (.).
Ví dụ:
#include
#include
using namespace std;
class SinhVien
{
private:
string hoten;
string masv;
float diem;
public:
void Nhap_thong_tin();
void Xuat_thong_tin();
protected:
string email;
//ham tao và ham huy
// sinhvien();
//~sinhvien();
};
void sinhvien::Nhap_thong_tin()
{
cout << « Nhap ho ten: « ;
getline (cin,hoten);
cout << « masv: « ;
//fflush(stdin);
getline (cin,masv);
cout << « Nhap diem: « ; cin >> diem;
}
void sinhvien::Xuat_thong_tin()
{
cout << « ho ten: »<< hoten<<endl;
cout << « ma so: »<< masv<<endl;
cout << « diem: »<< diem<<endl;
}
int main()
{
sinhvien NguyenVanA;
//cout <<« Nhap_thong_tin »<<endl;
NguyenVanA.Nhap_thong_tin();
//cout << « Xuat_thong_tin »<<endl;
NguyenVanA.Xuat_thong_tin();
system (« pause »);
return 0;}
-
Constructor & Destructor trong C++
Một class constructor là một hàm đặc biệt trong một lớp mà được gọi khi một đối tượng mới của lớp đó được tạo. Một class destructor cũng là một hàm đặc biệt mà được gọi khi đối tượng đã tạo bị hủy.
Copy Constructor trong C++: copy constructor là một constructor mà tạo một đối tượng bằng việc khởi tạo nó với một đối tượng của cùng lớp đó, mà đã được tạo trước đó.
Hàm Friend trong C++: hàm friend được cho phép truy cập tới các thành viên là private và protected của một lớp.
Hàm Inline trong C++: với một hàm inline, trình biên dịch cố gắng mở rộng code trong thân hàm thế chỗ cho một lời gọi tới hàm đó.
Con trỏ this trong C++: mỗi đối tượng có một con trỏ this đặc biệt, mà trỏ tới chính đối tượng đó.
Con trỏ tới lớp trong C++: một con trỏ tới một lớp được thực hiện giống hệt như cách một con trỏ tới một cấu trúc. Thực ra, một lớp là một cấu trúc với các hàm trong nó.
-
Bộ tiền xử lí
Bộ tiền xử lý (Preprocessor) là các directive (chỉ thị), cung cấp chỉ lệnh tới bộ biên dịch để tiền xử lý thông tin trước khi bắt đầu biên dịch thực sự.
Tất cả chỉ thị tiền xử lý (Preprocessor directive) bắt đầu với #, và chỉ có các ký tự khoảng trống trắng là có thể xuất hiện ở trước một chỉ thị tiền xử lý trên một dòng. Chỉ thị tiền xử lý không là các lệnh trong C++, vì thế chúng không kết thúc với một dấu chấm phảy.
VD: Chỉ thị tiền xử lý là #include trong tất cả ví dụ. Macro này được sử dụng để bao một Header file vào trong source file.
Có một số chỉ thị tiền xử lý được hỗ trợ bởi C++ như #include, #define …
Bộ tiền xử lý # define trong C++
Chỉ thị tiền xử lý #define tạo các biểu tượng hằng. Biểu tượng hằng là một macro và mẫu chung của chỉ thị tiền xử lý này trong C++ là:
#define ten_cua_macro ten_thay_the
Khi dòng này xuất hiện trong một file, tất cả macro xuất hiện theo sau trong file này sẽ được thay thế bởi ten_thay_the trước khi chương trình được biên dịch.
Ví dụ:
#include
using namespace std;
#define PI 3.14159
int main () {
cout << « Gia tri cua PI la: » << PI << endl; return 0; } Giả sử chúng ta có source file, sau đó biên dịch nó với tùy chọn –E và hướng kết quả tới test.p. Bây giờ, nếu bạn kiểm tra test.p, nó sẽ có nhiều thông tin và tại dưới cùng, bạn sẽ tinh chỉnh giá trị được thay thế như sau: $gcc -E test.cpp > test.p
…
int main () {
cout << « Gia tri cua PI la: » << 3.14159 << endl; return 0;
}
Biên dịch có điều kiện trong C++
Có một số chỉ thị tiền xử lý có thể sử dụng để biên dịch có sự tuyển chọn giữa các phần trong source code của bạn. Tiến trình này được gọi là biên dịch có điều kiện.
Chỉ lệnh tiền xử lý có điều kiện khá giống với cấu trúc lựa chọn if.
Ví dụ:
#ifndef NULL
#define NULL 0
#endif
Có thể biên dịch một chương trình với mục đích debug và có thể tắt hoặc bật việc debug này bởi sử dụng một macro trong C++, như sau:
#ifdef DEBUG cerr <<« Bien x = » << x << endl;
#endif
Lệnh cerr để được biên dịch trong chương trình nếu biểu tượng hằng DEBUG đã được định nghĩa ở trước chỉ thị #ifdef DEBUG. Có thể sử dụng lệnh #if 0 để chú thích một phần của chương trình, như sau:
#if 0
khong duoc bien dich phan code nay
#endif
-
Static and dynamic library
Thư viện (library) là một tập mã nguồn đã được đóng gói, có thể được tái sử dụng trong nhiều chương trình khác nhau.
- Thư viện trong ngôn ngữ C++ gồm 2 thành phần chính:
- Những header files khai báo các hàm có thể được sử dụng trong chương trình.
- Tập hợp mã nguồn đã được biên dịch thành mã máy tương ứng với phần định nghĩa của các hàm đã được khai báo trong các header files.
Nhiều thư viện khi cung cấp đã được biên dịch sẵn vì nhiều lý do. Thông thường, hiếm khi có sử chỉnh sửa trong phần thư viện, nên không cần phải biên dịch nhiều lần. Thư viện cũng được biên dịch sẵn thành mã máy để tránh người dùng truy cập và chỉnh sửa.
Có 2 kiểu thư viện: thư viện liên kết tĩnh (static library) và thư viện liên kết động (dynamic library).
-
Thư viện liên kết động – Dynamic Link library
Trong Windows thì các file thư viện này có đuôi là .dll, trong các hệ điều hành họ Linux thì chúng có đuôi là .so, trên MacOS thì là .dylib.
Trong đó chứa code, class, hàm… tất nhiên là không phải các loại code như C++, Java… mà là mã nhị phân, là ngôn ngữ bậc thấp của hệ điều hành, do đó chúng ta không thể mở nó ra như mở file text được. Khi chúng ta viết phần mềm bằng các ngôn ngữ cao cấp như Pascal, C++… thì các mã nguồn này sẽ được dịch dần dần qua mã Assembly rồi tới mã nhị phân. Các chương trình (hay các file .exe) có sử dụng đến thư viện liên kết động sẽ đọc code trong các file .dll (hay .so trên linux…) này để sử dụng trong quá trình chạy.
- Ưu điểm:
Thư viện liên kết động giảm thiểu số lượng code có trong chương trình của bạn, do đó chương trình bạn viết ra sẽ luôn gọn nhẹ hơn so với dùng thư viện liên kết tĩnh.
Thư viện liên kết động cho phép nhiều chương trình sử dụng nó một cách trực tiếp mà không cần phải biên dịch lại.
- Nhược điểm:
Sử dụng thư viện liên kết động sẽ làm cho thời gian chạy chương trình lâu hơn do phải truy cập file, đọc file… từ đĩa cứng… vốn là công việc đòi hỏi thời gian.
-
Thư viện liên kết tĩnh – Static library
Trong Windows thì chúng có đuôi .lib, trong Linux là .a. Cũng giống với thư viện liên kết động, thư viện liên kết tĩnh cũng chứa code nhị phân, chỉ khác là chúng được các chương trình gọi tới trong quá trình biên dịch. Khi chương trình của chúng ta được dịch từ các ngôn ngữ cấp cao sang mã nhị phân, chúng sẽ copy cả mã nguồn của các file thư viện tĩnh này vào trong mã nguồn của mình, tức là bây giờ code trong file .exe của bạn sẽ bao gồm code của cả file thư viện.
- Vậy tóm lại thư viện liên kết động gọi hàm từ các file .dll (hoặc .so) để chạy
Thư viện liên kết tĩnh thì copy code trong file .lib (hoặc .a) vào file .exe của mình để chạy. Vậy khi các file thư viện bị lỗi, chương trình của bạn có thể sẽ chỉ báo lỗi trong khi chạy nếu dùng file .dll, còn nếu dùng file .lib thì thư viện của bạn không thể chạy được, nói đúng hơn là không thể dịch được khi bị lỗi.
- Nhược điểm:
Thư viện liên kết tĩnh chúng sẽ làm cho chương trình của bạn phình to ra do phải copy code trong thư viện vào code của chính nó.
- Ưu điểm:
Tuy nhiên chương trình của bạn sẽ chạy rất nhanh, bởi vì chúng không mất thời gian mở các file .dll ra để đọc code, chúng đã có sẵn code trong RAM cùng với code của mình rồi, vì tốc độ đọc ghi trong RAM nhanh hơn tốc độ đọc ghi trong đĩa cứng rất nhiều lần.
Nguồn được tổng hợp từ : https://cpp.daynhauhoc.com
===========
Liên hệ : https://nguyencongtrinh1995.tumblr.com/
>> https://www.dailymotion.com/nguyencongtrinh
or :
kythuatysinhblog.wordpress.com/blog/
**Mọi đóng góp để blog phát triển hơn xin gửi vào tài khoản sau :
Số tài khoản 103001836696 -Thẻ Viettinbank -Chủ thẻ Nguyễn Công Trình.
Partager :
-
Partager
WordPress:
J’aime
chargement…
Articles similaires
Ký Hồng Phú