Menu

Hello World trong C++: chương trình đầu tiên, giải thích từng dòng

Giả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.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Chương trình

Đây là chương trình Hello World hoàn chỉnh bằng C++. Nhấn Chạy để biên dịch và thực thi ngay trong trình duyệt:

Chương trình in ra một dòng:

Hello, World!

Năm dòng code, mỗi dòng làm một việc cụ thể. Các phần dưới đây lần lượt đi qua từng dòng, rồi hướng dẫn cách build cùng tệp đó trên máy của bạn và giải thích ý nghĩa của những lỗi biên dịch đầu tiên thường gặp.

Từng dòng một

#include <iostream>

Những dòng bắt đầu bằng # là chỉ thị cho bộ tiền xử lý (preprocessor), chạy trước trình biên dịch chính. #include <iostream> chèn vào các khai báo từ header chuẩn <iostream> (các stream nhập xuất). Header này là nơi khai báo std::cout và std::endl. C++ không có câu lệnh in có sẵn; việc in ra là một phần của thư viện chuẩn, và bạn bật nó lên bằng dòng này.

int main() {

Mọi chương trình C++ đều bắt đầu chạy từ một hàm tên là main. Chương trình phải có đúng một hàm này, và tên phải viết thường. Chữ int đứng trước cho biết main trả về một số nguyên cho hệ điều hành khi kết thúc. Cặp ngoặc tròn rỗng nghĩa là ở đây hàm không nhận đối số nào, và dấu ngoặc nhọn mở { bắt đầu thân hàm.

std::cout << "Hello, World!" << std::endl;

Dòng này mới là dòng thực sự in ra màn hình.

  • std::cout là stream đầu ra chuẩn, thường là terminal. Tiền tố std:: cho biết cout nằm trong namespace std, nơi chứa toàn bộ thư viện chuẩn.
  • << là toán tử chèn (insertion operator). Nó đưa giá trị bên phải vào stream bên trái. Bạn có thể nối nhiều toán tử liên tiếp, mỗi << thêm phần tiếp theo vào cùng một đầu ra.
  • "Hello, World!" là một string literal: văn bản nằm trong dấu ngoặc kép.
  • std::endl kết thúc dòng.
  • Dấu chấm phẩy kết thúc câu lệnh. Mọi câu lệnh trong C++ đều cần nó.

return 0;

return kết thúc main và trả một giá trị về cho hệ điều hành. Theo quy ước, 0 nghĩa là chương trình chạy thành công, còn số khác báo hiệu có lỗi. Các script và công cụ build đọc mã thoát này. Bên trong main, dòng này không bắt buộc: nếu chương trình chạy đến dấu ngoặc nhọn đóng, C++ xử lý như thể bạn đã viết return 0;.

Dấu ngoặc nhọn đóng

Dấu ngoặc nhọn đóng kết thúc thân hàm main, và cùng với nó là cả chương trình.

std::endl và '\n'

Có hai cách phổ biến để kết thúc một dòng, và cả hai đều xuất hiện trong code thực tế:

Đầu ra:

Hello, World!
Hello again!
Line one
Line two

Kết quả nhìn thấy là như nhau. Khác biệt nằm ở chỗ std::endl ghi ký tự xuống dòng rồi flush stream, đẩy toàn bộ văn bản trong bộ đệm ra terminal ngay lập tức. '\n' chỉ ghi ký tự xuống dòng, và stream tự flush theo lịch riêng (muộn nhất là khi chương trình kết thúc). Trong một vòng lặp in hàng nghìn dòng, những lần flush thừa của std::endl tạo ra khác biệt đo được, nên nhiều lập trình viên C++ mặc định dùng '\n' và chỉ dùng std::endl khi văn bản cần hiện ra ngay. Ký tự thoát \n cũng dùng được bên trong chuỗi, như dòng thứ ba. Trang về nhập xuất trình bày cout và cin sâu hơn.

Phiên bản dùng using namespace std;

Nhiều tài liệu hướng dẫn viết Hello World như sau:

using namespace std; bảo trình biên dịch tìm trong namespace std những tên mà nó không tìm thấy ở chỗ khác, nhờ vậy cout và endl dùng được mà không cần tiền tố. Cách này ổn với các chương trình nhỏ và bài tập. Trong code lớn hơn và trong các tệp header, người ta thường tránh nó, vì nó kéo hàng trăm tên chuẩn vào phạm vi và các tên này có thể trùng với tên của bạn (ví dụ một hàm bạn tự viết tên là count hay distance). Viết std::cout chỉ tốn thêm năm ký tự mà loại bỏ hẳn rủi ro đó.

Biên dịch và chạy Hello World trên máy của bạn

Trình soạn thảo trên trình duyệt biên dịch giúp bạn. Trên máy của mình, bạn tự làm hai bước tương tự: biên dịch tệp mã nguồn thành tệp thực thi, rồi chạy tệp thực thi đó. Trước hết bạn cần cài một trình biên dịch C++; hướng dẫn cài đặt chỉ cách thiết lập trên Windows, macOS và Linux.

Lưu chương trình thành hello.cpp, mở terminal trong cùng thư mục, rồi biên dịch:

g++ hello.cpp -o hello

Nếu không có gì được in ra là đã thành công, và giờ có một tệp thực thi tên hello (hello.exe trên Windows) nằm cạnh tệp mã nguồn. Chạy nó:

./hello

Trên Windows, hãy chạy hello.exe hoặc chỉ hello. Trên macOS, clang++ hello.cpp -o hello cũng hoạt động y như vậy, và g++ ở đó thường chính là Clang dưới một cái tên khác.

Có hai cờ nên thêm ngay từ đầu: -std=c++17 (hoặc -std=c++20) chọn chuẩn ngôn ngữ, còn -Wall -Wextra bật các cảnh báo giúp bắt những lỗi thật:

g++ -std=c++17 -Wall -Wextra hello.cpp -o hello

Trang về biên dịch C++ giải thích các cờ này làm gì, -o nghĩa là gì, và vì sao không có nó bạn sẽ nhận được một tệp tên a.out.

Những lỗi đầu tiên thường gặp

Các thông báo lỗi dưới đây là của GCC (g++). Clang diễn đạt khác nhưng chỉ vào cùng một dòng.

Thiếu dấu chấm phẩy.

hello.cpp:5:5: error: expected ';' before 'return'

Trình biên dịch chỉ nhận ra thiếu ; khi đọc đến token tiếp theo, nên số dòng được báo thường nằm sau chỗ sai một dòng. Hãy kiểm tra cuối dòng phía trước.

Thiếu #include <iostream>.

error: 'cout' is not a member of 'std'

std::cout được khai báo trong <iostream>. Thêm dòng include vào đầu tệp.

Thiếu std::.

error: 'cout' was not declared in this scope; did you mean 'std::cout'?

Hoặc viết std::cout và std::endl, hoặc thêm using namespace std; sau dòng include.

Viết Main thay vì main. C++ phân biệt chữ hoa chữ thường. Một chương trình có int Main() vẫn biên dịch được, nhưng thất bại ở bước liên kết với lỗi undefined reference to 'main', vì trình liên kết không tìm thấy hàm mà chương trình phải bắt đầu chạy từ đó.

Biên dịch bằng gcc thay vì g++. gcc hello.cpp biên dịch code C++ nhưng không liên kết thư viện chuẩn C++, nên bạn nhận về một loạt lỗi undefined reference to std::.... Hãy dùng g++ (hoặc clang++) cho tệp C++.

Dấu ngoặc kép cong. Code sao chép từ trình soạn thảo văn bản hay từ một trang web có thể chứa dấu ngoặc kép kiểu in ấn (“Hello”) thay vì dấu ngoặc kép thẳng ("Hello"). GCC báo lỗi stray '\342' in program. Hãy gõ lại các dấu ngoặc kép trong trình soạn thảo code.

Header cũ và void main. Một số tài liệu rất cũ dùng #include <iostream.h> hoặc void main(). Cả hai đều không phải C++ chuẩn: header là <iostream> không có .h, và main phải trả về int. Các trình biên dịch hiện đại đều từ chối cả hai.

In bằng std::println trong C++23

C++23 bổ sung một cách in dòng ngắn gọn hơn, std::println trong header <print>:

#include <print>

int main() {
    std::println("Hello, World!");
}

Hàm này tự thêm ký tự xuống dòng và hỗ trợ placeholder {} cho các giá trị. Nó được hỗ trợ từ GCC 14, Clang 18 với libc++, và các phiên bản Visual Studio gần đây, và cần cờ -std=c++23. Phần lớn code và tài liệu hiện có vẫn dùng std::cout, nên bạn nên thành thạo cả hai.

Câu hỏi thường gặp

Viết Hello World bằng C++ như thế nào?

Bắt đầu bằng #include <iostream>, sau đó định nghĩa int main() và đặt std::cout << "Hello, World!" << std::endl; vào bên trong, tiếp theo là return 0;. Lưu tệp thành hello.cpp, biên dịch bằng g++ hello.cpp -o hello, rồi chạy ./hello.

Vì sao Hello World trong C++ cần #include <iostream>?

std::cout và std::endl được khai báo trong header <iostream>, chứ không có sẵn trong ngôn ngữ. Thiếu dòng include, trình biên dịch không biết các tên này và dừng lại với lỗi như 'cout' is not a member of 'std'.

std::endl và '\n' khác nhau thế nào?

Cả hai đều kết thúc dòng. std::endl còn flush bộ đệm đầu ra, buộc văn bản được đẩy ra ngay. '\n' chỉ ghi ký tự xuống dòng và để stream tự flush khi đến lúc, nhanh hơn khi bạn in nhiều dòng. Với một dòng Hello World thì không có khác biệt nào nhìn thấy được.

Có cần return 0 ở cuối main trong C++ không?

Không. main là hàm duy nhất mà C++ cho phép bỏ return; chạy đến dấu ngoặc nhọn đóng được coi như return 0;, báo cho hệ điều hành biết chương trình chạy thành công. Nhiều người vẫn viết nó để mã thoát được thể hiện rõ ràng.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu