Tài liệu C++
Tài liệu tham khảo C++ ngắn gọn, đi kèm ví dụ. Đọc khái niệm, xem code, rồi luyện tập trong một hành trình Coddy.
Bắt đầu khóa họcBắt đầu
- C++ là gìC++ thực sự là gì, vì sao nó biên dịch thẳng ra mã máy gốc, và những loại phần mềm hiệu năng cao được xây dựng bằng C++.
- Hello WorldGiải thích từng dòng chương trình Hello World trong C++: #include <iostream>, int main(), std::cout và <<, std::endl so với '\n', return 0, cùng cách biên dịch và sửa những lỗi người mới gặp đầu tiên.
- Cài đặt C++Cách cài trình biên dịch C++ (GCC, Clang hoặc MSVC), chọn bộ công cụ phù hợp với hệ điều hành, và kiểm tra nó hoạt động từ dòng lệnh.
- Biên dịch C++Cách C++ biến mã nguồn .cpp thành tệp thực thi gốc: biên dịch bằng g++ (hoặc clang++/MSVC), chạy tệp nhị phân, và đọc lỗi biên dịch khi có sự cố.
- Cú pháp C++Các quy tắc cú pháp cốt lõi của một chương trình C++: câu lệnh và dấu chấm phẩy, khối lệnh trong ngoặc nhọn, hàm main và cách in ra màn hình, giải thích từ chương trình đầu tiên.
- Chú thíchCách viết chú thích trong C++, gồm ghi chú một dòng // và khối nhiều dòng /* */, cùng cách vô hiệu hóa code bằng chú thích, vì sao chú thích khối không lồng nhau được, và thế nào là một chú thích đáng giữ lại.
Biến và kiểu dữ liệu
- BiếnBiến trong C++ hoạt động thế nào: khai báo kèm kiểu, khác biệt giữa gán và khởi tạo, khởi tạo bằng ngoặc nhọn, quy tắc đặt tên và phạm vi quyết định nơi biến tồn tại và biến mất.
- Kiểu dữ liệuTìm hiểu thực tế các kiểu dữ liệu cơ bản của C++: số nguyên, số thực, char và bool, cùng kích thước, signed và unsigned, literal và hậu tố, tràn số và cách chọn đúng kiểu.
- Từ khóa autoCách từ khóa `auto` để trình biên dịch tự suy ra kiểu của biến cho bạn: những gì nó lược bỏ, khi nào nó thật sự hữu ích, và những cái bẫy hay làm người mới vấp.
- Hằng số và constCách khai báo giá trị chỉ đọc trong C++ bằng const, khác biệt giữa const và constexpr, con trỏ const và con trỏ tới const, cùng hàm thành viên const.
- Toán tửTìm hiểu toán tử trong C++: số học, so sánh, logic, gán và bitwise, cùng những cái bẫy quanh phép chia số nguyên, độ ưu tiên và cơ chế short-circuit.
- Ép kiểuÉp kiểu trong C++ hoạt động thế nào: chuyển đổi ngầm định, cái bẫy chia số nguyên và bốn phép ép kiểu có tên (static_cast, const_cast, reinterpret_cast, dynamic_cast), kèm những cái bẫy gây mất dữ liệu âm thầm.
Luồng điều khiển
- if-elseCách ra quyết định trong C++ với if, else if và else: điều kiện, nối nhiều nhánh, lồng nhau, toán tử ba ngôi, if có khởi tạo, và những cái bẫy hay khiến bạn vấp.
- switchGiải thích câu lệnh switch trong C++: nhãn case, break và fall-through, nhánh default, gom nhiều case, dùng switch với enum và những bẫy khi khai báo biến bên trong case.
- Vòng lặp forCách lặp lại code bằng vòng lặp for trong C++: phần đầu ba thành phần, đếm lên và đếm xuống, duyệt mảng, lồng vòng lặp, break và continue, cùng lỗi lệch một và lỗi unsigned mà ai cũng gặp.
- Vòng lặp whileGiải thích vòng lặp while trong C++: while kiểm tra điều kiện trước, do-while chạy ít nhất một lần, lặp đến giá trị sentinel, break và continue, cùng cách tránh vòng lặp vô hạn.
- for dạng rangeGiải thích vòng lặp for dạng range trong C++: duyệt gọn gàng qua mảng, vector, string và map, vì sao nên dùng auto& và const auto&, và những cái bẫy sao chép, iterator mất hiệu lực cần tránh.
Hàm
- HàmCách viết hàm trong C++: cấu trúc kiểu trả về, tên và tham số, khai báo và định nghĩa, trả về giá trị, hàm void, cùng các lỗi hay gặp như thiếu return hay quên prototype.
- Tham số hàmCách đối số đi vào hàm C++: truyền tham trị và truyền tham chiếu, tham chiếu const để đọc nhanh mà không sửa, đối số mặc định, con trỏ, và những cái bẫy sao chép âm thầm làm chậm chương trình.
- Tham chiếuGiải thích tham chiếu trong C++: dấu & trong tham số tạo ra một tên khác như thế nào, vì sao truyền tham chiếu tránh sao chép và cho hàm sửa biến của nơi gọi, khi nào dùng const& và khi nào nên trả về giá trị.
- Nạp chồng hàmNạp chồng hàm trong C++ cho phép nhiều hàm dùng chung một tên, miễn là danh sách tham số khác nhau. Tìm hiểu cách phân giải nạp chồng chọn hàm phù hợp, vì sao chỉ khác kiểu trả về là không đủ, và các bẫy mơ hồ, đối số mặc định cần tránh.
- LambdaViết nhanh những hàm nhỏ ngay tại chỗ bằng lambda trong C++: cú pháp, cách capture hoạt động, khi nào dùng `mutable`, và cái bẫy dangling capture mà ai cũng từng dính.
Con trỏ và bộ nhớ
- Con trỏCon trỏ C++ giải thích từ đầu: khai báo con trỏ, toán tử lấy địa chỉ & và giải tham chiếu *, nullptr, con trỏ tới mảng, cùng những cái bẫy con trỏ treo và con trỏ chưa khởi tạo gây crash chương trình.
- Tham chiếu và con trỏSo sánh thực tế giữa tham chiếu và con trỏ trong C++: điểm chung, điểm khác (gắn lại, null, số học con trỏ) và một quy tắc rõ ràng để chọn cái nào trong code hằng ngày.
- Bộ nhớ độngCách cấp phát bộ nhớ lúc chạy bằng `new`, giải phóng bằng `delete`, và tránh rò rỉ bộ nhớ, con trỏ treo, double free khi tự quản lý heap.
- Smart pointerSmart pointer sở hữu vùng nhớ heap và tự giải phóng nó. Tìm hiểu `unique_ptr`, `shared_ptr`, `make_unique` và `make_shared`, và vì sao bạn gần như không bao giờ phải viết `new`/`delete` nữa.
Chuỗi và nhập xuất
- ChuỗiCách dùng `std::string` trong C++: tạo, nối, tìm kiếm và cắt văn bản một cách an toàn, và vì sao bạn gần như không bao giờ nên dùng `char*` thô cho công việc thực tế.
- Nhập và xuấtCách nhập xuất qua console hoạt động trong C++: in ra bằng cout, đọc bằng cin, bug kinh điển về ký tự xuống dòng khi dùng getline sau cin, và cách khôi phục khi nhập liệu thất bại.
- std::getlineCách std::getline đọc trọn một dòng vào std::string: dùng với cin, vì sao nó trả về chuỗi rỗng sau cin >>, cách sửa bằng cin.ignore và std::ws, ký tự phân tách tùy chọn, và đọc tệp từng dòng đến hết tệp.
- String streamCách dùng std::stringstream, istringstream và ostringstream để phân tích văn bản, tách chuỗi theo khoảng trắng, chuyển đổi giữa chuỗi và số, và tạo chuỗi có định dạng ngay trong bộ nhớ.
Container STL
- MảngGiải thích mảng thô trong C++: cách khai báo và khởi tạo, truy cập bằng chỉ số an toàn, duyệt mảng theo kích thước, cái bẫy mảng suy biến thành con trỏ, và vì sao std::array và vector thường tốt hơn.
- vectorstd::vector là mảng có thể thay đổi kích thước của C++, container bạn nên dùng mặc định. Tìm hiểu cách tạo, truy cập, mở rộng và duyệt vector, cùng những cái bẫy về iterator bị vô hiệu và truy cập ngoài phạm vi.
- mapGiải thích std::map trong C++: container khóa và giá trị được sắp xếp, tra cứu với độ phức tạp logarit. Thêm, tìm, duyệt, và tránh cái bẫy kinh điển operator[] âm thầm thêm khóa mới.
- unordered_mapTìm hiểu std::unordered_map trong C++, người anh em dùng bảng băm của map với thao tác thêm và tra cứu trung bình O(1). Gồm các thao tác cơ bản, cái bẫy [] tự thêm khóa, count và find, và khi nào nên chọn nó thay cho map có thứ tự.
- setCách std::set lưu các giá trị duy nhất và tự động sắp xếp trong C++: thêm phần tử, kiểm tra tồn tại bằng count và find, duyệt theo thứ tự, và khác biệt giữa set, multiset và unordered_set.
- pair và tupleCách `std::pair` và `std::tuple` gom hai hay nhiều giá trị vào một đối tượng: cách tạo, cách truy cập từng thành phần, structured binding và khi nào nên dùng loại nào.
- IteratorCách iterator trong C++ hoạt động như con trỏ tổng quát vào container: begin() và end(), dereference, tiến tới, các biến thể const và reverse, cùng các bẫy invalidation và dereference end() gây undefined behavior.
Thuật toán STL và template
- Thuật toánDùng các thuật toán chuẩn của C++ như `find`, `count_if`, `transform`, `accumulate`, `remove` để xử lý dữ liệu trên một range mà không cần tự viết vòng lặp, kèm những cái bẫy về cặp iterator và erase-remove.
- Sắp xếpSắp xếp vector và mảng trong C++ bằng `std::sort`: thứ tự mặc định, comparator tùy chỉnh, sắp xếp struct theo một trường, và cái bẫy strict weak ordering gây crash.
- TemplateViết code một lần và dùng được cho mọi kiểu với template trong C++: function template, class template, suy luận kiểu và những lỗi biên dịch khó hiểu mà chúng gây ra.
Lớp và đối tượng
- LớpTìm hiểu cách lớp trong C++ gom dữ liệu và hành vi thành các kiểu dùng lại được: khai báo biến thành viên và phương thức, tạo đối tượng, phân chia public/private, và những cái bẫy như thành viên chưa khởi tạo và con trỏ this.
- Hàm khởi tạoHàm khởi tạo là hàm thành viên đặc biệt chạy khi đối tượng được tạo ra. Tìm hiểu hàm khởi tạo mặc định, có tham số và sao chép, danh sách khởi tạo thành viên, và cách tránh để đối tượng ở trạng thái khởi tạo dở dang.
- Hàm hủyHàm hủy tự động chạy khi một đối tượng bị hủy. Tìm hiểu cú pháp `~ClassName()`, khi nào nó được gọi, vì sao nó giải phóng tài nguyên, và Rule of Three/Five.
- Kế thừaTìm hiểu cách kế thừa trong C++ cho phép lớp dẫn xuất dùng lại và mở rộng lớp cơ sở: cú pháp, kế thừa public và private, thứ tự gọi hàm khởi tạo và hàm hủy, cùng các bẫy như object slicing.
- Hàm ảoHàm ảo cho phép một con trỏ lớp cha gọi phiên bản phương thức của lớp con lúc chạy. Tìm hiểu `virtual`, `override`, lớp trừu tượng và vì sao hàm hủy của lớp cha phải là hàm ảo.
- Nạp chồng toán tửNạp chồng toán tử trong C++ cho phép kiểu dữ liệu của bạn dùng được các toán tử có sẵn như +, == và <<. Tìm hiểu quy tắc hàm thành viên và hàm không thành viên, cách nạp chồng toán tử so sánh và toán tử stream, và các bẫy về kiểu trả về và toán tử gán.
- Phạm vi truy cậpCách public, private và protected kiểm soát ai được chạm vào các thành viên của một lớp trong C++: nền tảng của tính đóng gói, cùng getter, setter và lối thoát friend.
- StructGiải thích struct trong C++: cách gom các biến liên quan thành một kiểu duy nhất, khai báo và khởi tạo đối tượng struct, thêm hàm thành viên và hàm khởi tạo, và struct thực sự khác class ở điểm nào.
- enumTìm hiểu enum trong C++: cách khai báo, vì sao enum class có phạm vi an toàn hơn enum thường, giá trị tùy chỉnh, dùng switch với enum, và chuyển đổi qua lại với số nguyên.
Lỗi và gỡ lỗi
- Ngoại lệNgoại lệ báo những lỗi mà một hàm không tự xử lý được tại chỗ. Tìm hiểu cách `throw`, các kiểu ngoại lệ chuẩn, thông báo `what()`, và vì sao ngoại lệ tốt hơn mã lỗi trả về với những lỗi quan trọng.
- try-catchBọc đoạn code có rủi ro trong `try`, phản ứng trong `catch`. Tìm hiểu cách bắt ngoại lệ bằng tham chiếu const, sắp xếp nhiều khối catch, dùng `catch (...)` và ném lại mà không rò rỉ tài nguyên.
- Hành vi không xác địnhHành vi không xác định (UB) là code mà chuẩn C++ không đặt ra quy tắc nào: nó có thể sập, làm hỏng dữ liệu hoặc trông như chạy đúng. Tìm hiểu các nguyên nhân thường gặp, vì sao "chạy được" chẳng chứng minh gì, và các công cụ bắt UB.