Writing Your First Program in C++: A Visual, Hands-On Guide
Write, compile and run your first C++ program, and understand every line of it: main, #include, std::cout, newlines and std::endl, exit codes, reading compiler errors, reading input, compiler flags, real measurements, and exercises with answers.

On this page
Every programmer's journey starts the same way: making the computer say Hello, World! In C++ that takes just five lines, but those five lines hide a surprising amount: a function the operating system calls, tens of thousands of lines of library code pulled in by a single #include, and a number handed back to the system when the program ends.
In this guide you'll write, compile and run your first C++ program, then take it apart line by line. You'll see what the compiler actually produces, learn to read its error messages (you'll see plenty of them!), print text and numbers, read input from the keyboard, and finish with exercises.
All outputs and measurements below come from real runs with GCC 14.1 (g++) on Windows. Other compilers print slightly different messages, but the programs behave the same.
What you need: a compiler
C++ is a compiled language. You write the program as text (the source code), and a compiler translates it into an executable file of machine instructions your processor runs directly. The three popular compilers are GCC (g++), Clang (clang++) and Microsoft's MSVC.
| System | How to get a compiler |
|---|---|
| Windows | Install MSYS2 and run pacman -S mingw-w64-ucrt-x86_64-gcc for g++, or install Visual Studio with the "Desktop development with C++" workload for MSVC |
| macOS | Run xcode-select --install in the Terminal for clang++ (also available as g++) |
| Linux | Run sudo apt install g++ (Debian, Ubuntu) or sudo dnf install gcc-c++ (Fedora) |
Check that it works:
$ g++ --version
g++.exe (Rev3, Built by MSYS2 project) 14.1.0From source code to running program

When you run g++, four things happen in a row:
- The preprocessor handles lines starting with
#, like#include, by pasting in other files. - The compiler translates the C++ into machine instructions.
- The linker joins your code with the compiled standard library into one executable.
- You run the executable, and the operating system starts it by calling
main.
The smallest C++ program
This is a complete, valid C++ program:
int main() {
}mainis the function where every C++ program starts. The operating system calls it when the program launches.intis its return type:mainhands an integer back to the system when it finishes.- The parentheses
()hold the function's parameters; here there are none. - The curly braces
{ }enclose the function's body, the instructions to run. It's empty, so the program starts and immediately ends.
Save it as empty.cpp, then compile and run it. On macOS and Linux:
1$ g++ empty.cpp -o empty
2$ ./empty
3$ echo $?
40-o empty names the output file. On Windows, g++ adds .exe, and you run it as empty.exe in Command Prompt or .\empty.exe in PowerShell. It prints nothing, as expected. The echo $? shows the number the program handed back: 0. More on that number soon.
Hello, World!
Now let's make it talk. Save this as hello.cpp:
1#include <iostream>
2
3int main() {
4 std::cout << "Hello, World!" << std::endl;
5 return 0;
6}Compile and run:
$ g++ hello.cpp -o hello
$ ./hello
Hello, World!Congratulations, you're a C++ programmer! Now let's understand every piece.

#include <iostream>brings in the input/output stream library, which definesstd::cout. The angle brackets< >mean "a standard library header".std::cout(say "see-out", for character output) represents the console. It lives in thestdnamespace, the standard library's own "folder" of names, hence thestd::prefix.<<is the insertion operator: it pushes whatever is on its right into the stream on its left. The arrows point the way the data flows."Hello, World!"is a string literal: text between double quotes. The quotes themselves aren't printed.std::endlends the line (more on that below).;ends each statement, like a period ends a sentence.return 0;endsmainand reports success.
What #include really brings in
That one #include line does a lot of work. We asked g++ to show the preprocessor's output (g++ -E) for an empty main with different headers and C++ standards:

Your Hello World is about 0.02% of what the compiler reads, and the newer the C++ standard, the more <iostream> brings along. Don't worry about it for small programs, but it explains why large C++ projects can take minutes to compile, and why you include only what you use.
Lines, "\n" and std::endl
Without a line ending, the output just stops where it is. Take out the << std::endl and the terminal's prompt ends up glued to your text:
$ ./hello
Hello, World!$There are two ways to end a line:
"\n", the newline character, written inside a string. The backslash starts an escape sequence:\nis a newline,\ta tab,\"a double quote and\\a backslash.std::endl, which writes a newline and flushes the output: it forces everything waiting in the output buffer to be written out right away.
Flushing sounds harmless, but it's slow when you do it a lot. We wrote one million lines to a file both ways:

Same file, about 51 times faster with "\n". Most C++ programmers use "\n" by default, so that's what the rest of this guide does:
1#include <iostream>
2
3int main() {
4 std::cout << "Hello, World!\n";
5 std::cout << "Tabs:\tone\ttwo\n";
6 std::cout << "Quotes: \"C++\" and a backslash: \\\n";
7 return 0;
8}Hello, World!
Tabs: one two
Quotes: "C++" and a backslash: \Printing more than text
<< can be chained, and it prints numbers and the results of calculations too:
1#include <iostream>
2
3int main() {
4 std::cout << "C++ was first released in " << 1985 << ".\n";
5 std::cout << "2 + 3 = " << 2 + 3 << "\n";
6 std::cout << "7 / 2 = " << 7 / 2 << "\n";
7 std::cout << "7.0 / 2 = " << 7.0 / 2 << "\n";
8 std::cout << "Line one\n"
9 << "Line two\n";
10 return 0;
11}1C++ was first released in 1985.
22 + 3 = 5
37 / 2 = 3
47.0 / 2 = 3.5
5Line one
6Line twoNotice 7 / 2 printed 3: dividing two whole numbers in C++ throws away the remainder. Make one of them a decimal (7.0) and you get 3.5. A statement can also span several lines; only the ; ends it.
return 0 and exit codes
The int that main returns is the program's exit code: a number the operating system keeps after the program ends. By convention, 0 means success and anything else means some kind of failure.
1#include <iostream>
2
3int main() {
4 std::cout << "Something went wrong!\n";
5 return 3;
6}1$ ./fail
2Something went wrong!
3$ echo $?
43
5$ ./fail && echo "This only runs if fail succeeded"
6Something went wrong!
7$ ./hello && echo "This only runs if hello succeeded"
8Hello, World!
9This only runs if hello succeeded
Scripts, build tools and test runners all rely on exit codes. (In PowerShell, use $LASTEXITCODE instead of $?.) As a special rule, if main reaches its closing brace without a return, it returns 0 automatically, which is why the empty program worked. Writing return 0; makes the intent clear.
When things go wrong: compiler errors
You will make typos, and the compiler will catch them before the program ever runs. Learning to read its messages is a superpower. Here's the first mistake everyone makes, a missing semicolon:
1#include <iostream>
2
3int main() {
4 std::cout << "Hello, World!" << std::endl
5 return 0;
6}1nosemicolon.cpp: In function 'int main()':
2nosemicolon.cpp:4:46: error: expected ';' before 'return'
3 4 | std::cout << "Hello, World!" << std::endl
4 | ^
5 | ;
6 5 | return 0;
7 | ~~~~~~
The format is always file:line:column: error: message, followed by the code with a ^ pointing at the spot. GCC even suggests the fix.
Forget the #include, and the compiler doesn't know what std::cout is:
1int main() {
2 std::cout << "Hello, World!" << std::endl;
3 return 0;
4}1noinclude.cpp: In function 'int main()':
2noinclude.cpp:2:10: error: 'cout' is not a member of 'std'
3 2 | std::cout << "Hello, World!" << std::endl;
4 | ^~~~
5noinclude.cpp:1:1: note: 'std::cout' is defined in header '<iostream>'; this is probably fixable by adding '#include <iostream>'
6 +++ |+#include <iostream>
7 1 | int main() {(It goes on with the same kind of error for std::endl.) Forget the std:: prefix:
1#include <iostream>
2
3int main() {
4 cout << "Hello, World!" << endl;
5 return 0;
6}1nostd.cpp: In function 'int main()':
2nostd.cpp:4:5: error: 'cout' was not declared in this scope; did you mean 'std::cout'?
3 4 | cout << "Hello, World!" << endl;
4 | ^~~~
5 | std::coutAnd forget a closing quote, and the error points at where the string started:
1#include <iostream>
2
3int main() {
4 std::cout << "Hello, World! << std::endl;
5 return 0;
6}1typo.cpp:4:18: warning: missing terminating " character
2 4 | std::cout << "Hello, World! << std::endl;
3 | ^
4typo.cpp:4:18: error: missing terminating " character
5 4 | std::cout << "Hello, World! << std::endl;
6 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
7typo.cpp: In function 'int main()':
8typo.cpp:5:5: error: expected primary-expression before 'return'
9 5 | return 0;
10 | ^~~~~~One typo, two errors: the second is just fallout from the first. Always fix the first error first, then compile again.
What about using namespace std;?
Many tutorials write using namespace std; near the top so they can type cout instead of std::cout. It works, but it pulls hundreds of standard names into your program, where they can clash with your own (try naming a variable count or distance). In small learning programs it's harmless; in real code, and especially in header files, most style guides say to write std::. This guide sticks with std::.
Reading input from the keyboard
std::cin (say "see-in") is the console's input stream, and >>, the extraction operator, pulls a value out of it into a variable:
1#include <iostream>
2
3int main() {
4 int first;
5 int second;
6 std::cout << "First number: ";
7 std::cin >> first;
8 std::cout << "Second number: ";
9 std::cin >> second;
10 std::cout << first << " + " << second << " = " << first + second << "\n";
11 return 0;
12}A sample run, where the numbers after the colons are typed by the user:
First number: 12
Second number: 30
12 + 30 = 42int first; declares a variable, a named box that holds one integer. To read a whole line of text, such as a full name, use std::getline with a std::string:
1#include <iostream>
2#include <string>
3
4int main() {
5 std::string name;
6 std::cout << "What's your name? ";
7 std::getline(std::cin, name);
8 std::cout << "Hello, " << name << "! Welcome to C++.\n";
9 return 0;
10}What's your name? Ada Lovelace
Hello, Ada Lovelace! Welcome to C++.Useful compiler flags
g++ hello.cpp -o hello is enough to start, but a few flags make the compiler much more helpful:
| Flag | What it does |
|---|---|
-o name | Names the executable |
-std=c++20 | Uses the C++20 standard (newer features; -std=c++23 is newer still) |
-Wall -Wextra | Turns on warnings about suspicious code |
-O2 | Optimizes the program for speed |
-g | Adds debugging information |
Warnings point at code that compiles but is probably a mistake:
1#include <iostream>
2
3int main() {
4 int score = 10;
5 int unused = 5;
6 std::cout << "Score: " << score << "\n";
7 return 0;
8}1$ g++ -std=c++20 -Wall -Wextra warnings.cpp -o warnings
2warnings.cpp: In function 'int main()':
3warnings.cpp:5:9: warning: unused variable 'unused' [-Wunused-variable]
4 5 | int unused = 5;
5 | ^~~~~~Unlike errors, warnings still produce a program, but it's a good habit to fix every one. A good everyday command is g++ -std=c++20 -Wall -Wextra hello.cpp -o hello.
A modern alternative: std::println
C++23 added std::println, which prints with a line ending and fills {} placeholders, a style borrowed from Python and Rust:
1#include <print>
2
3int main() {
4 std::println("Hello, {}!", "World");
5 std::println("{} + {} = {}", 2, 3, 2 + 3);
6}Hello, World!
2 + 3 = 5It needs a recent compiler and -std=c++23. With GCC 14 on Windows (MinGW), also add -lstdc++exp at the end of the command. Most existing C++ code and tutorials use std::cout, so it's worth knowing both.
Your turn: practice
Try these before peeking at the answers. Compile each with g++ -std=c++20 -Wall -Wextra.
Exercise 1: Predict the output (warm-up). What exactly does this print?
1#include <iostream>
2
3int main() {
4 std::cout << "One";
5 std::cout << "Two\n";
6 std::cout << "Three\n\nFour\n";
7 std::cout << 10 / 4 << " " << 10.0 / 4 << "\n";
8 return 0;
9}Exercise 2: Fix the program. This has three mistakes. Find them by compiling it and reading the errors.
1#include <iostream>
2
3int main() {
4 std::cout << "I am learning C++\n"
5 cout << "It is fun!\n";
6 std::cout << "Bye" << std:endl;
7 return 0;
8}Exercise 3: Draw a box. Write a program that prints exactly this:
+--------+
| C++! |
+--------+Exercise 4: A tiny calculator. Read two whole numbers and print their sum, difference, product and quotient, like this sample run:
1First number: 17
2Second number: 5
317 + 5 = 22
417 - 5 = 12
517 * 5 = 85
617 / 5 = 3Exercise 5: Temperature converter (challenge). Read a temperature in degrees Celsius as a whole number and print it in Fahrenheit, using the formula F = C × 9 / 5 + 32. Make sure 37 °C gives 98.6, not 98.
Quick quiz
- Which function does every C++ program start in?
- What does
#include <iostream>give you? - What's the difference between
"\n"andstd::endl? - What does
return 0;at the end ofmainmean? - A compiler reports 10 errors. Which one should you fix first?
Answers
Exercise 1: "One" has no line ending, so "Two" continues on the same line. "\n\n" makes an empty line. 10 / 4 divides whole numbers, giving 2, while 10.0 / 4 gives 2.5:
1#include <iostream>
2
3int main() {
4 std::cout << "One";
5 std::cout << "Two\n";
6 std::cout << "Three\n\nFour\n";
7 std::cout << 10 / 4 << " " << 10.0 / 4 << "\n";
8 return 0;
9}1OneTwo
2Three
3
4Four
52 2.5Exercise 2: A missing semicolon at the end of line 4, a missing std:: before cout, and std: with one colon instead of two:
1#include <iostream>
2
3int main() {
4 std::cout << "I am learning C++\n";
5 std::cout << "It is fun!\n";
6 std::cout << "Bye" << std::endl;
7 return 0;
8}I am learning C++
It is fun!
ByeExercise 3: One line of output per statement:
1#include <iostream>
2
3int main() {
4 std::cout << "+--------+\n";
5 std::cout << "| C++! |\n";
6 std::cout << "+--------+\n";
7 return 0;
8}+--------+
| C++! |
+--------+Exercise 4: Remember that / on two ints throws away the remainder:
1#include <iostream>
2
3int main() {
4 int first;
5 int second;
6 std::cout << "First number: ";
7 std::cin >> first;
8 std::cout << "Second number: ";
9 std::cin >> second;
10 std::cout << first << " + " << second << " = " << first + second << "\n";
11 std::cout << first << " - " << second << " = " << first - second << "\n";
12 std::cout << first << " * " << second << " = " << first * second << "\n";
13 std::cout << first << " / " << second << " = " << first / second << "\n";
14 return 0;
15}1First number: 17
2Second number: 5
317 + 5 = 22
417 - 5 = 12
517 * 5 = 85
617 / 5 = 3Exercise 5: Writing 9.0 instead of 9 turns the calculation into decimal math, so nothing gets cut off:
1#include <iostream>
2
3int main() {
4 int celsius;
5 std::cout << "Temperature in Celsius: ";
6 std::cin >> celsius;
7 std::cout << celsius << " C = " << celsius * 9.0 / 5 + 32 << " F\n";
8 return 0;
9}Temperature in Celsius: 37
37 C = 98.6 FTemperature in Celsius: -40
-40 C = -40 FWith celsius * 9 / 5 + 32, 37 × 9 = 333, and 333 / 5 = 66 in whole-number division, giving 98 instead of 98.6.
Quiz: (1) main. (2) The input/output streams, including std::cout and std::cin. (3) Both end the line, but std::endl also flushes the output buffer, which made writing a million lines about 51 times slower in our test. (4) The program finished successfully: 0 is the "success" exit code. (5) The first one: later errors are often caused by it.
Cheat sheet
| I want to… | Write |
|---|---|
| Start a program | int main() { … } |
Use std::cout and std::cin | #include <iostream> |
| Print text | std::cout << "Hello\n"; |
| Print several things | std::cout << "Sum: " << 2 + 3 << "\n"; |
| End a line | "\n" (or std::endl to also flush) |
| Print a tab / quote / backslash | \t / \" / \\ |
| Read a number | int age; std::cin >> age; |
| Read a whole line | std::string line; std::getline(std::cin, line); |
| Report success / failure | return 0; / return 1; |
| Compile | g++ -std=c++20 -Wall -Wextra hello.cpp -o hello |
| Run | ./hello (macOS, Linux) or hello.exe (Windows) |
Wrapping up
Five lines, and now you know what each one does:
- Every C++ program starts in
main, and itsintreturn value is the exit code: 0 means success. #include <iostream>brings in the input/output library; in our measurement, that one line expands to about 24,600 lines (49,432 with C++23).std::cout <<prints text, numbers and calculations;std::cin >>reads input.- End lines with
"\n";std::endlalso flushes, which was about 51 times slower for a million lines. - The compiler is your friend: read
file:line:column: error, fix the first error first, and turn on-Wall -Wextra. - Building means preprocessing, compiling and linking your 97 bytes into a 119 KB executable.
Next, learn how to create a variable in C++, then make decisions with the if statement and repeat things with the for loop. For the bigger picture, read What Is the C++ Programming Language?.
Read next

Ruby Blocks and Iterators: Write Your Own
Learn how Ruby methods receive blocks, pass values with yield, handle a missing block, and return an Enumerator. Build and run your own iterator.

C++ std::vector: Size, Capacity, and Safe Growth
Learn how std::vector grows in C++: the difference between size and capacity, when reserve helps, why resize is different, and how growth can invalidate references.

How to Handle Errors in Go: A Hands-On Guide
Learn Go's everyday error pattern with runnable examples: return an error, check it, add context with %w, and recognize a missing file with errors.Is.
Comments
Be kind and specific. Comments with links from new accounts appear after a moderator reviews them.