Bài 3: Làm Quen Với C++

Chương trình đầu tiên, Hello World

Mã nguồn

1#include <iostream>
2using namespace std;
3
4// main() is where program execution begins.
5int main() {
6   cout << "Hello World. My name AlexBlack."; // prints Hello World. My name AlexBlack.
7   return 0;
8}

Các bạn hãy thực hiện các bước mình mô tả kỹ ở bên dưới

  • Mở text editor bất kỳ, ví dụ visual studio code.

  • Tạo 1 file text, đặt tên là main.cpp

  • Copy đoạn mã lệnh bên dưới, quăng vào file main.cpp vừa tạo

  • Mở terminal (cmd trên windown), cd vào thư mục chưa file main.cpp bạn vừa tạo.

  • Gõ ‘g++ hello.cpp’ và ấn nút enter. Nếu không có bất kỳ lỗi nào xảy ra, sau khi thực thi xong đoạn lệnh trên, chương trình sẽ sinh ra 1 file có tên là a.out

  • gõ ‘a.out’ để chạy chương trình

  • Bạn sẽ nhìn thấy dòng chữ “Hello World. My name AlexBlack.” trên màn hình terminal của bạn

1g++ main.cpp
2./a.out
3Hello World. My name AlexBlack.

Giải thích:

Một chương trình c++ là một tổ hợp bao gồm nhiều câu lệnh, mỗi câu lệnh có nhiệm vụ và chức năng khác nhau, với đoạn code helloworld phía trên, chương trình có chứa các thành phần.

  • Dòng đầu tiên, khai báo header thư viện mà chúng ta sử dụng. Ở đây, chúng ta sử dụng thư viện iostream. Đây là thư viện cơ bản, nằm trong bộ thư viện chuẩn của c++.

  • Dòng tiếp theo using namespace std; báo cho trình biên dịch biết sử dụng namespace std. Khái niệm namespace mình sẽ đề cập ở các chương tiếp theo, đến chương đó, các bạn sẽ hiểu lý do dùng nó, có nên xóa nó đi hay không. Ở bước cơ bản này, các bạn chỉ việc copy đoạn lệnh này rồi quăng vào xài, đừng thắc mắc, phân tâm.

  • Dòng tiếp theo // main() is where program execution begins. Đây là đoạn comment 1 dòng trong c++. Trình biên dịch gặp // thì sẽ bỏ qua, không biên dịch nội dung ở sau đoạn //. Comment 1 dòng được bắt đầu bởi dấu //, và kết thúc bởi ký tự xuống dòng.

  • Dòng *int main() * là tên hàm chính. Bất kỳ một chương trình c++ nào, đều có hàm bắt đầu là main. Trình biên dịch sẽ tìm hàm main để bắt đầu chạy thực thi.

  • Dòng cout « “Hello World. My name AlexBlack.”; // prints Hello World. My name AlexBlack. in ra dòng chữ Hello World. My name AlexBlack. lên màn hình

  • Dòng *return 0; * kết thúc chương trình, trả về giá trị 0 cho chương trình cha gọi chương trình của mình đang viết.

  • Ở tiếng việt, chúng ta kết thúc câu bởi dấu ‘chấm(.)’. Ngôn ngữ C/C++ kết thúc câu bởi dấu chấm phẩy ‘;’. Ở ví dụ trên, câu ‘cout « “Hello World. My name AlexBlack.”;’ được kết thúc bởi dấu chấm phẩy. Nếu thiếu dấu chấm phẩy, trình biên dịch sẽ báo lỗi cú pháp (có đề cập ở mục lỗi, bên dưới)

Comment trong c++

C++ hỗ trợ hai loại comment. Comment một dòng và comment nhiều dòng

Comment một dòng, bắt đầu bằng dấu // kết thúc bằng ký tự xuống dòng. Ví dụ như đoạn mã lệnh hello world ở trên, có 2 cái comment 1 dòng.

Ví dụ:

1trời nắng, đường vắng

Comment nhiều dòng, bắt đầu bằng dấu /*, kết thúc bằng đấu */. Khi bạn muốn viết 1 đoạn chú thích dài, nêu nổi bật vấn đề đang gặp phải, hoặc cách xử lý hay của bạn, hoặc bất kỳ vấn đề gì mà bạn muốn note lại để sau này đọc rõ hơn.

1/* hôm nay trời nắng chang chang
2mèo con đi học chẳng mang thứ gì */

Một câu hỏi thường được đặt ra là có nên comment hay không. Theo ý kiến riêng của mình là nên. Comment càng nhiều càng tốt, càng chi tiết càng tốt. Tất nhiên là chúng ta phải comment trọng tâm của vấn đề, tránh comment lang mang.

Thử đặt trường hợp, bạn viết 1 hàm tìm điểm rơi của viên bi sắt có khối lượng x khi ném bằng tay phải với góc ném y và lực ném z. 1 tuần sau bạn đọc lại đoạn mã nguồn đó, bạn tự tin rằng mình sẽ hiểu bao nhiêu phần?

Errors and Warnings

Lỗi là một hoạt động bất hợp pháp được thực hiện bởi người dùng dẫn đến hoạt động bất thường của chương trình.

Các lỗi lập trình thường không bị phát hiện cho đến khi chương trình được biên dịch hoặc thực thi. Một số lỗi ngăn cản chương trình được biên dịch hoặc thực thi. Vì vậy, các lỗi cần được loại bỏ trước khi biên dịch và thực thi.

Các lỗi phổ biến nhất có thể được phân loại như sau.

Lỗi trong C++
Syntax errors Run-time Errors Linker Errors Logical Errors

1. Syntax errors (lỗi cú pháp)

Là lỗi khi mình vi phạm các luật của việc viết code c++. Các lỗi dạng này thường được phát hiện bởi trình biên dịch, nên nó còn có tên gọi khác là compile-time errors. Khi gặp lỗi này, chúng ta sẽ không biên dịch thành công mã nguồn của chương trình.

Một số lỗi cú pháp phổ biến:

  • Viết thiếu dấu ;

  • Viết thiếu dấu đóng ngoặc/mở ngoặc.

  • Sử dụng biến chưa được khai báo.

 1 // C++ program to illustrate syntax error
 2 
 3#include <iostream>
 4 
 5int main()
 6{
 7    int x = 10;
 8    int y = 15;
 9     
10    std::cout << " "<< x<< z <<std::endl // semicolon missed
11
12    return 0;
13}
14 
15//Mã nguồn này được viết và chia sẻ bởi Phạm Duy Tùng.

Khi chạy dòng code lên, ta sẽ gặp thông báo lỗi:

1main.cpp:11:41: error: expected ';' after expression
2    std::cout << " "<< x<< z <<std::endl // semicolon missed
3                                        ^
4                                        ;
5main.cpp:11:28: error: use of undeclared identifier 'z'
6    std::cout << " "<< x<< z <<std::endl // semicolon missed
7                           ^
82 errors generated.

Đoạn báo lỗi trên nhắc là chúng ta thiếu đấu ; sau biểu thước ở dòng 11 cột 41. Và sử dụng biến z chưa được khai báo.

2. Run-time Errors

Lỗi xảy ra trong quá trình chạy chương trình, khi chương trình đã build thành công. Một lỗi phổ biến trong nhóm lỗi này là lỗi chia cho 0.

 1// C++ program to illustrate Run-time error
 2 
 3#include <iostream>
 4 
 5int main()
 6{
 7    int x = 10;
 8    int x = 0;
 9    std::cout << " "<< x/ z <<std::endl; // run-time error
10
11    return 0;
12}
13 
14//Mã nguồn này được viết và chia sẻ bởi Phạm Duy Tùng.

3. Linker Errors

Lỗi này xảy ra khi ta viết chương trình có sử dụng thêm thư viện ngoài, hoặc thư viện do chính chúng ta viết. Trong quá trình biên dịch, trình biên dịch đã biên dịch thành công các file, nhưng không thể liên kết các file lại với nhau.

1// C++ program to illustrate Linker error
2#include <iostream>
3int Main()
4{
5    return 0;
6}
7 
8//Mã nguồn này được viết và chia sẻ bởi Phạm Duy Tùng.

Trong C/C++ quy định hàm main phải là chữ main (viết thường), ở đây chương trình không tìm được hàm main để bắt đầu thực thi, nên báo lỗi như bên dưới.

1Undefined symbols for architecture arm64:
2  "_main", referenced from:
3     implicit entry/start for main executable
4ld: symbol(s) not found for architecture arm64
5clang: error: linker command failed with exit code 1 (use -v to see invocation)

4. Logical Errors

Lỗi này xảy ra khi chúng ta nhỡ tay gõ một cái gì đó sai trái làm cho đoạn chương trình không làm đúng theo logic đã được thiết kế từ trước.

 1// C++ program to illustrate Logical error
 2#include<iostream>
 3using namespace std;
 4 
 5int main(){
 6    // logical error : a semicolon after loop
 7    int i=1;
 8    while (true);
 9    {
10        i++;
11        if(i>10)return i;
12    }
13    
14    return 0;
15}
16//Mã nguồn này được viết và chia sẻ bởi Phạm Duy Tùng.

Ví dụ trên, mình đã nhỡ tay gõ thêm ký tự ; sau vòng lặp while, làm chương trình lặp vô tận và không có lối thoát.

1main.cpp:7:17: warning: while loop has empty body [-Wempty-body]
2    while (true);
3                ^
4main.cpp:7:17: note: put the semicolon on a separate line to silence this warning
51 warning generated.

Trong trường hợp mình mắc các lỗi phổ biến, trình biên dịch có thể đưa ra cảnh báo và đưa ra nhắc nhở cho chúng ta.

Câu lệnh và hàm

Câu lệnh

Câu lệnh là một phần chương trình c/c++, được thực thi một cách tuần tự.

Ví dụ

 1// C++ program to illustrate statement
 2#include<iostream>
 3using namespace std;
 4 
 5int main(){
 6    // logical error : a semicolon after loop
 7    int i=1; // câu lệnh khai báo declaration statement
 8    while (true) //Câu lệnh điều kiện
 9    {
10        i++; //Câu lệnh biểu thức
11        if(i>10) //Câu lệnh điều kiện
12            return i; //Câu lệnh return
13    }
14    
15    return 0; //Câu lệnh return.
16}
17//Mã nguồn này được viết và chia sẻ bởi Phạm Duy Tùng.

Hàm

Hàm là nhóm các câu lệnh lại với nhau, để thực hiện một nhiệm vụ. Một chương trình c++ có ít nhất 1 hàm main.

Bạn có thể tùy ý tách các đoạn code nhỏ ra thành nhiều hàm khác nhau. Phụ thuộc vào phong cách code của bạn. Không ai quy định phải tách hàm như thế nào cả. Thông thường, các lập trình viên sẽ tách hàm theo chức năng, công dụng của hàm.

Cấu trúc một hàm bao gồm :

1return_type function_name( parameter list ){
2    body ;
3}

Trong thư viện c++ chuẩn có cung cấp cho chúng ta kha khá các hàm được xây dựng sẵn, ví dụ hàm làm tròn lên ceil, hàm làm tròn xuống floor. Các bạn có tham khảo trong https://en.cppreference.com/w/cpp/header.

Nhập, xuất dữ liệu

Thư viện C++ hỗ trợ chúng ta nhiều thư viện nhập xuất. Trong C++, dữ liệu được thực hiện là một chuỗi tuần tự các byte. Từ chuyên ngành là streams. Vì vây, nên chia làm 2 dạng.

  • Input stream: Chuỗi các byte được đưa từ bên ngoài (bàn phím, mạng lan, file …) vào trong bộ nhớ -> gọi là chuỗi dữ liệu nhập , hay gọi là nhập liệu.

  • Output stream: chuỗi các byte từ bộ nhớ chính đi ra (hiển thị lên màn hình, , qua mạng lan, ra đèn led … ) -> gọi là chuỗi dữ liệu xuất.

Ở đây, mình sẽ sử dụng iostream có trong thư viện cơ sở của C++ làm ví dụ minh họa, ngoài ra, c++ còn có iomanip và fstream, các bạn có thể tìm hiểu thêm

 1
 2// C++ program to illustrate data stream
 3#include<iostream>
 4using namespace std;
 5 
 6int main(){
 7  int age;
 8 
 9    cout << "nhap vao so tuoi cua ban: ";
10    cin >> age;
11    cout << endl<<"Tuoi cua ban la: " << age<<endl;
12 
13    return 0;
14}
15 
16//Mã nguồn này được viết và chia sẻ bởi Phạm Duy Tùng.

Trong ví dụ trên, mình sử dụng hàm nhập liệu là cin ( đọc là xi in), có sẵn trong iostream. Hàm sẽ nhận các ký tự mình gõ trên bàn phím, kết thúc bởi dấu enter ( giả sử mình nhập số 5 rồi ấn enter). Bản chất bên trong là các ký tự mình gõ trên bàn phím sẽ biến thành mỗi chuỗi tuần tự các byte (stream) và đẩy vào trong bộ nhớ ram.

Để hiển thị lên màn hình, chúng ta dùng hàm cout ( đọc là xi ao). Bản chất bên trong là dữ liệu chúng ta muốn hiển thị lên màn hình sẽ mã hóa thành chuỗi tuần tự byte và đẩy ra các thiết bị ngoại vi.

1nhap vao so tuoi cua ban: 5
2
3Tuoi cua ban la: 5

Phân biệt C++ Standard library và STL

STL và C++ Standard library là 2 ông khác biệt hoàn toàn, phân biệt như sau.

C++ Standard library

C++ Standard library là tập các thư viện chuẩn của C Standard Library, được viết lại dưới dạng tên khác, thông thường là bị xóa .h đi và thêm chữ c ở đầu. Ví dụ thư viện time.h trong c sẽ được xào nấu thành ctime

STL

STL là từ viết tắt của Standard Template Library , là thư viện bao gồm 4 thành phần chính là algorithms, containers, Numeric, và iterators. Giúp tăng sự linh hoạt và mềm dẻo của C++. Cụ thể

Container

Containers - tiếng việt dịch ra là thùng chứa, là đối tượng dùng để chứa các đối tượng khác. Container lưu trữ và quản lý các đối tượng, cung cấp các hàm để truy xuất đến các đối tượng.

Container được phân loại như sau:

  • Sequence containers

    • vector
    • deque
    • list
  • Associative containers

    • set
    • multiset
    • map
    • multimap
    • hash_set
    • hash_map
    • hash_multiset
    • hash_multimap
  • Containers adpators

    • Stack
    • Queue
    • Priority_queue

Phụ thuộc vào bài toán mà chúng ta sẽ lựa chọn container phù hợp để đáp ứng độ phức tạp và thời gian thực thi. Không nên xài đại 1 loại container nào đó.

Iterators

Iterators là đối tượng giúp lập trình viên duyệt containers. Chỉ có 2 loại nhóm container là Sequence container và Associative container mới có iterator

Có 5 loại iterators được hỗ trợ trong c++ là:

  • input (dùng để đọc chuỗi giá trị)
  • output (dùng để ghi chuỗi giá trị)
  • forward ( đọc, ghi, di chuyển lên đến 1 vùng khác)
  • bidirectional (đọc, ghi , di chuyển lên, di chuyển xuống)
  • random access (nhảy tự do đến 1 bước khác)

Algorithms

Algorithms chứa tập các hàm giúp xử lý nhiều phần tử. Ví dụ sort dùng để xắp xếp các phần tử theo thứ tự. binary_search giúp tìm kiếm dữ liệu dạng nhị phân, cho tốc độ tìm kiếm cao hơn….

Numeric

Là tập các thư viện hỗ trợ lập trình viên thực hiện các phép toán trên số. Ví dụ complex hỗ trợ các template và các hàm tính toán số phức.

Comments