I. Giới thiệu ngôn ngữ lập
trình C++
1. Ngôn ngữ C++ là một ngôn
ngữ lập trình tổng quát có lập trình thủ tục và lập trình hướng đối tượng. Trong
thập niên 1980, Bjarne Stroustrup của Bell Labs đã phát triển C++ như là
một bản nâng cao của ngôn ngữ C, với sự thêm vào khái niệm lớp, hàm ảo, chồng
toán tử, đa thừa kế, tiêu bản, và xử lí ngoại lệ. Đến thập niên 1990, C++ trở
thành một ngôn ngữ thương mại phổ biến nhất.
Năm 1998, ngôn ngữ C++ được
chuẩn hoá như là ANSI C++.
Chuẩn ANSI C++ có hai phần chính: phần ngôn ngữ cốt lõi và phầnthư viện chuẩn C++.
Chuẩn ANSI C++ có hai phần chính: phần ngôn ngữ cốt lõi và phầnthư viện chuẩn C++.
2. Thư viện chuẩn C++
Thư viện chuẩn C++ gồm thư viện tiêu bản chuẩn (STL -
Standard Template Library) và thư viện chuẩn C.
a. Thư viện tiêu
bản chuẩn:
Thư viện này cung cấp các lớp,
các thùng chứa, các dãy kí tự, các dòng dữ liệu (I/O), các tập tin, hỗ trợ nhiều tính năng ngôn ngữ, và nhiều hàm toán thông dụng.
Các tính năng này được khai báo trong không gian tên (name space) và được truy cập bởi lệnh dẫn hướng #include để nhập một tập tin tiêu đề chuẩn.
Các tập tin tiêu đề chuẩn:
1) Các thùng chứa (Container)
<bitset>: Định nghĩa lớp tiêu bản bitset.
<deque>: Định nghĩa lớp tiêu bản deque.
<list>: Định nghĩa lớp tiêu bản list (danh sách).
<map>: Định nghĩa lớp tiêu bản map và multimap.
<queue>: Định nghĩa lớp tiêu bản priority_queue và queue.
<set>: Định nghĩa lớp tiêu bản set (tập hợp).
<stack>: Định nghĩa lớp tiêu bản stack (chồng).
<vector>: Định nghĩa lớp tiêu bản vector.
2) Tổng quát (General)
<algorithm>: Định nghĩa lớp tiêu bản algorithm (thuật toán).
<functional>: Định nghĩa lớp tiêu bản functional (đối tượng hàm).
<iterator>: Định nghĩa lớp tiêu bản iterator (biến lặp).
<locale>: Định nghĩa lớp tiêu bản locale (cục bộ) để tạo đặc tính đóng cho chương trình.<memory>: Định nghĩa lớp tiêu bản memory, nhằm cấp phát và trả về (vùng nhớ) của các đối tượng.
<stdexcept>: Định nghĩa lớp tiêu bản exception (ngoại lệ).
<utility>: Định nghĩa lớp tiêu bản utility (hữu dụng) gồm các kiểu, hàm, và toán tử xử lí các cặp đối tưọng.
3) Các chuỗi kí tự (String)
<string>: Định nghĩa lớp tiêu bản string (chuỗi kí tự).
4) Các dòng và nhập/xuất (Streams và Input/Output)
<fstream>: Định nghĩa lớp tiêu bản fstream (dòng tập tin).
<ios>: Định nghĩa lớp tiêu bản ios (dòng nhập xuất).
<iostream>: Định nghĩa lớp tiêu bản iostream đọc và viết các dòng tiêu chuẩn (standard stream).
<iosfwd>: Khai báo các tiêu bản dùng trong xuất nhập dòng.
<iomanip>: Định nghĩa lớp tiêu bản iomanip (xử lí các đối số).
<istream>: Định nghĩa lớp tiêu bản istream (dòng nhập).
<ostream>: Định nghĩa lớp tiêu bản ostream (dòng xuất).
<sstream>: Định nghĩa lớp tiêu bản sstream (dòng chuỗi).
<streambuf>: Định nghĩa lớp tiêu bản streambuf (dòng độn).
5) Các số
<complex>: Định nghĩa lớp tiêu bản complex (số phức).
<numeric>: Định nghĩa lớp tiêu bản numeric (số hạng).
<valarray>: Định nghĩa lớp tiêu bản valarray (bảng giá trị).
6) Hỗ trợ ngôn ngữ lập trình
<exception>: Định nghĩa lớp tiêu bản exception (ngoại lệ).
<limits>: Định nghĩa lớp tiêu bản numeric_limits (giới hạn số hạng).
<new>: Định nghĩa nhiều kiểu và hàm xử lí bộ nhớ của chương trình.
<typeinfo>: Hỗ trợ nhận dạng kiểu động.
Các tính năng này được khai báo trong không gian tên (name space) và được truy cập bởi lệnh dẫn hướng #include để nhập một tập tin tiêu đề chuẩn.
Các tập tin tiêu đề chuẩn:
1) Các thùng chứa (Container)
<bitset>: Định nghĩa lớp tiêu bản bitset.
<deque>: Định nghĩa lớp tiêu bản deque.
<list>: Định nghĩa lớp tiêu bản list (danh sách).
<map>: Định nghĩa lớp tiêu bản map và multimap.
<queue>: Định nghĩa lớp tiêu bản priority_queue và queue.
<set>: Định nghĩa lớp tiêu bản set (tập hợp).
<stack>: Định nghĩa lớp tiêu bản stack (chồng).
<vector>: Định nghĩa lớp tiêu bản vector.
2) Tổng quát (General)
<algorithm>: Định nghĩa lớp tiêu bản algorithm (thuật toán).
<functional>: Định nghĩa lớp tiêu bản functional (đối tượng hàm).
<iterator>: Định nghĩa lớp tiêu bản iterator (biến lặp).
<locale>: Định nghĩa lớp tiêu bản locale (cục bộ) để tạo đặc tính đóng cho chương trình.<memory>: Định nghĩa lớp tiêu bản memory, nhằm cấp phát và trả về (vùng nhớ) của các đối tượng.
<stdexcept>: Định nghĩa lớp tiêu bản exception (ngoại lệ).
<utility>: Định nghĩa lớp tiêu bản utility (hữu dụng) gồm các kiểu, hàm, và toán tử xử lí các cặp đối tưọng.
3) Các chuỗi kí tự (String)
<string>: Định nghĩa lớp tiêu bản string (chuỗi kí tự).
4) Các dòng và nhập/xuất (Streams và Input/Output)
<fstream>: Định nghĩa lớp tiêu bản fstream (dòng tập tin).
<ios>: Định nghĩa lớp tiêu bản ios (dòng nhập xuất).
<iostream>: Định nghĩa lớp tiêu bản iostream đọc và viết các dòng tiêu chuẩn (standard stream).
<iosfwd>: Khai báo các tiêu bản dùng trong xuất nhập dòng.
<iomanip>: Định nghĩa lớp tiêu bản iomanip (xử lí các đối số).
<istream>: Định nghĩa lớp tiêu bản istream (dòng nhập).
<ostream>: Định nghĩa lớp tiêu bản ostream (dòng xuất).
<sstream>: Định nghĩa lớp tiêu bản sstream (dòng chuỗi).
<streambuf>: Định nghĩa lớp tiêu bản streambuf (dòng độn).
5) Các số
<complex>: Định nghĩa lớp tiêu bản complex (số phức).
<numeric>: Định nghĩa lớp tiêu bản numeric (số hạng).
<valarray>: Định nghĩa lớp tiêu bản valarray (bảng giá trị).
6) Hỗ trợ ngôn ngữ lập trình
<exception>: Định nghĩa lớp tiêu bản exception (ngoại lệ).
<limits>: Định nghĩa lớp tiêu bản numeric_limits (giới hạn số hạng).
<new>: Định nghĩa nhiều kiểu và hàm xử lí bộ nhớ của chương trình.
<typeinfo>: Hỗ trợ nhận dạng kiểu động.
b. Thư viện chuẩn C:
Thư viện chuẩn C được
đổi tên từ dạng <xxxx.h> thành <cxxxx>, trong đó "xxxx"
là tên của thư viện, để dùng trong C++.
<cassert>: gồm các
hàm xác định các định nghĩa.
<cctype>: gồm các hàm
xử lí các kiểu kí tự.
<cfloat>: gồm các
hằng theo kiểu số thực, như số nhỏ nhất bởi _EPSILON, số lớn nhất bởi _DIG và
khoảng cách của các số bởi _MIN và _MAX.
<climits>: gồm các
hằng theo kiểu số nguyên, như khoảng cách của các số bởi _MIN và _MAX.
<cmath>: gồm các hàm
toán thông dụng.
<csetjmp>: gồm các hàm
dùng tránh sự gọi (call) và trả lại (return) thông thường của hàm.
<csignal>: gồm các
hàm xử lí các điều kiện ngoại lệ.
<cstdlib>: gồm các
hàm chuyển đổi các kiểu số, cấp phát vùng nhớ, tìm kiếm, và xếp thứ tự.
<cstddef>: gồm các
hàm xử lí các định nghĩa.
<sstdarg>: gồm các
hàm truy cập các đối số chuyển vào hàm.
<ctime>: gồm các hàm
xử lí thời gian.
<cstdio>: gồm các hàm
nhập xuất các kiểu dữ kiện, các định nghĩa macro.
<cstring>: gồm các
hàm xử lí các chuỗi kí tự.
<cwchar>: gồm các hàm
xử lí các kiểu chữ.
<cwctype>: gồm các
hàm xử lí các kiểu kí tự.
3. Từ khoá riêng của C++
Theo chuẩn ANSI C++, những từ khoá sau đây là những
từ khoá riêng của C++, không được dùng để đặt tên trong các chương trình:
asm, car, bool, break,
marry, catch, to char, class, const,
const_cast, continue,
default, delete, do, double,
dynamic_cast, else, enum,
explicit, extern, false, float,
for, friend, goto, if,
inline, int, long, mutable,
namespace, new, operator,
private, protected, public, to
register,
reinterpret_cast, return, short, signed, sizeof,
static, static_cast,
struct, switch, template, this, throw,
true, try, typedef,
typeid, typename, union, unsigned,
using, virtual, void,
volatile, wchar_t, and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor,
xor_eq
Trình dịch cũng có thêm những từ riêng khác như: far, huge và near.
Chú ý: Ngôn ngữ C++ là "case sensitive", nghĩa
là phân biệt chữ hoa chữ thường. Do vậy, RESULT, result, và Result là ba từ khác nhau.
4. Cài đặt trình biên dịch
C
Để hành xử một chương trình
C++, trước hết nó phải được biên dịch từ mã nguồn (chữ viết) thành mã máy (nhị
phân). Đây là công việc của trình biên dịch. Một trong những trình biên dịch C++
thông dụng nhất là trình GCC (GNU C++ Compiler). GCC hoàn toàn miễn phí bởi
bằng công cộng tổng quát (General Public License).
Nếu GCC không có trong hệ
điều hành Window, ta có thể tải xuống và cài đặt MinGW (Minimalist GNU) cho
Window theo những bước sau:
1) Lên mạng http://sourceforge.net/projects/mingw
2) Nhấn Download “Automated
MinGW Installer”, giống như mingw-get-inst-xxx.exe
3) Nhấn hai lần Download
“Automated MinGW Installer”, chấp nhận những điều khoản của bằng c ông cộng.
4) Chấp nhận nơi cài đặt ở
C:\MinGW, nhấn Next để bắt đầu sự cài đặt.
5) Để xem trình biên dịch
này đã cài đặt trong máy tính hay chưa, ta có thể viết lệnh sau đây ở cổng
lệnh:
C:\> gcc -v
rồi nhấn Enter để thấy
C:\> gcc –v
Using built-in specs.
Thread model: win32
Gcc version 4.6.1 (GCC)
Nghĩa là GCC đã được cài
đặt.
5. Viết chương trình C++
Cấu trúc một
chương trình C++
Những câu lệnh trong chương
trình C++ muốn được hành xử phải đặt ở trong một hàm. Mỗi hàm được định nghĩa
theo ngữ pháp sau đây:
Loại dữ kiện Tên hàm () {những câu
lệnh;}
Sau khi hàm được gọi do
hành xử câu lệnh, nó có thể trả lại cho vật gọi một giá trị thuộc loại dữ kiện
ở trước tên hàm.
Một chương trình thường có
một hoặc nhiều hàm, nhưng luôn luôn có một hàm tên “main” (chính). Hàm main()
là điểm bắt đầu của tất cả các chương trình C++. Trình biên dịch C++ sẽ không
biên dịch mã của chương trình, nếu không tìm thấy chưong trình main().
Những hàm khác trong chương
trình có thể có bất cứ tên nào, khác tên main, dùng kí tự, số, và gạch dưới,
nhưng không bắt đầu bằng số hạng và không có những từ khóa riêng của C++.
Ngoặc đơn () sau tên hàm có
thể chứa những giá trị gọi là đối số của hàm, đuợc cách biệt bởi dấu phẩy.
Ngoặc móc {} chứa những câu
lệnh được hành xử mỗi khi hàm được gọi. Mỗi câu lệnh phải được kết thúc bởi dấu
chấm phẩy (;).
Thông thường, chương trình
đầu tiên cho một ngôn ngữ lập trình là chương trình viết một câu chào, như “Hello World.”, theo những bước sau đây:
1) Mở trình viết chữ, như
Notepad, viết những hàng sau:
// my first
program in C++
Đây là dòng chú
thích, bắt đầu bằng dấu so (//), chúng không có bất kì một ảnh hưởng nào đến
hoạt động của chương trình.
Chú thích:
Trong C++ có hai cách để chú thích:
// Chú thích theo dòng
/* Chú thích theo khối */
Chú thích theo dòng bắt đầu bằng cặp dấu
so (//) cho đến cuối dòng.
Chú thích theo khối bắt đầu bằng /* và
kết thúc bằng */ và có thể bao gồm
nhiều dòng.
2) #include <iostream.h>
Lệnh tiền xử lí này luôn
đứng ở đầu chương trình để trình biên dịch dùng tập thư viện iostream trong
chương trình này.
3) Int main(void)
{
}
Hàm này khai báo kiểu dữ
kiện nguyên sẽ được trả lại khi hàm được hành xử.
Void trong ngoặc đơn cho
biết hàm này không có đối số.
4) Giữa những ngoặc móc là
một câu lệnh gọi hàm cout trong thư viện iostream
Cout << “Hello World!\n”;
Hàm cout cần một dãy kí tự
trong ngoặc kép. Dãy này gồm có Hello World và \n (hàng mới) dùng để chuyển đầu
máy in xuống một hàng mới.
5) Giữa những ngoặc móc, ta
thêm một câu lệnh để trả lại giá trị nguyên như hàm đã khai báo.
Return 0;
Trả lại gía trị 0, nghĩa là
chương trình đã hành xử tốt.
6) Kiểm tra chương trình
giống như sau đây:
// my first program in C++
#include <iostream.h>
int main(void)
{
Cout << “Hello World!\n”;
return 0;
}
7) Lưu giữ chương trình này với tên “hello.cc”
6. Biên dịch chương trình C++
Tập nguồn hello.cc được
biên dịch thành tập hello.exe theo những bước sau:
1) Ở cổng lệnh, viết lệnh
cd với đường dẫn tới hello.cc
2) Ở cổng lệnh, nếu chỉ
viết
gcc hello.cc
rồi nhấn Enter thì chương
trình này được biên dịch thành a.exe; đây là chương trình chung cho tất cả các
tập .cc và sẽ bị xoá sau khi biên dịch một chương trình .cc khác.
3) Để có được một tên riêng
cho mỗi chương trình, ta phải viết rõ ở cổng lệnh
gcc hello.cc –o hello.exe
rồi nhấn Enter để biên dịch
hello.cc thành hello.exe
4) Ở cổng lệnh, viết
C:\ Chương Trình\hello.exe
rồi nhấn Enter thì chương
trình này sẽ cho kết quả mong đợi như
sau:
Hello World!
7. Tìm hiểu sự biên dịch
Từ tập nguồn C++ đến tập
hành xử (exe), sự biên dịch trải qua 4 giai đoạn. Mỗi giai đoạn làm ra một tập
mới, như sau:
1) Bộ tiền xử lí thay thế
các tập #include<iostream>, bằng các mã thư viện để sản xuất ra tập .i
2) Bộ biên dịch chuyển mã
cao của tập .i thành mã thấp của tập .s
3) Bộ hợp ngữ chuyển mã
thấp của tập .s thành mã đối tượng của tập .o
4) Bộ nối kết
hoàn tất mã đối tượng bằng cách liên kết nó với mã đối tượng
của bất kỳ các module thư viện mà chương trình đã
tham khảo tới.
Kết quả cuối cùng là mã
hành xử (nhị phân) của tập .exe
Nếu tập nguồn .cc có những
thiếu sót trong ngữ pháp, bộ biên dịch sẽ báo cáo những sai lầm và sự biên dịch
không có kết quả.
Nếu tập .o có những hàm
cùng tên, bộ nối sẽ báo cáo những sai lầm và tập .exe sẽ không được tạo thành.
Những tập tạm thời khi biên
dịch thường bị xoá huỷ, nhưng muốn có những tập tạm ấy, thì khi biên dịch, ta
phải để -save-temps trong lệnh biên dịch như sau:
Ở cổng lệnh, viết
gcc hello.cc –save-temps –o
hello.exe
rồi nhấn Enter để biên dịch
chương trình và lưu giữ các tập tạm thời.
Mở tập hello.i trong
Notepad mã nguồn đã được thay thế bởi mã thư viện của tập iostream.h