Skip to content

C++ Syntax and Program Structure

Syntax is the set of rules for writing code the compiler can understand, like grammar in English. C++ is strict: one missing semicolon or a wrong capital letter stops the whole program from compiling. The good news is that the rules are few and consistent. This lesson takes a small program apart line by line, then covers output, input, comments and the compiler errors every beginner meets.

You should have a working compiler from the installation lesson. All programs were compiled with g++ 14.2 (-std=c++20 -Wall -Wextra), and the outputs shown are real.

The structure of a C++ program

// syntax.cpp - the building blocks of a C++ program
#include <iostream>   // gives us std::cout and std::cin
#include <string>     // gives us std::string

/*
   Every C++ program starts running in main().
*/
int main()
{
    std::string name = "Asha";   // a statement ends with a semicolon
    int year = 2026;

    std::cout << "Name: " << name << '\n';
    std::cout << "Year: " << year << std::endl;

    // Escape sequences
    std::cout << "Tab:\tafter a tab\n";
    std::cout << "Quote: \"C++\" and backslash: \\\n";

    // Several values in one statement
    std::cout << "2 + 3 = " << 2 + 3 << '\n';

    return 0;   // 0 tells the operating system "success"
}
Output
Name: Asha
Year: 2026
Tab:	after a tab
Quote: "C++" and backslash: \
2 + 3 = 5

Every C++ program has the same skeleton:

#include ...          <-- 1. preprocessor directives: which libraries you use

int main()            <-- 2. the main function: where execution starts
{                     <-- 3. opening brace: start of the function body
    statements;       <-- 4. the work, one statement at a time, each ending with ;
    return 0;         <-- 5. exit status for the operating system
}                     <-- closing brace

Line by line

#include <iostream>

Lines that start with # are preprocessor directives. They're handled before compilation. #include <iostream> copies in the header that declares input/output tools such as std::cout and std::cin. <string> gives you std::string. Rule of thumb: include a header for everything you use, and don't put a semicolon after #include.

HeaderProvides
<iostream>std::cout, std::cin, std::cerr, std::endl
<string>std::string, std::getline, std::to_string
<cmath>std::sqrt, std::pow, std::round
<iomanip>std::setprecision, std::setw, std::fixed
<limits>std::numeric_limits (ranges of types)

int main()

main is the entry point: the operating system starts your program by calling it. Every program needs exactly one main. The int before it means main returns a whole number to the operating system. The empty () means it takes no arguments here.

Braces { }

Curly braces group statements into a block: the body of a function, a loop or an if. Every { needs a matching }. Variables declared inside a block exist only inside it (see variables).

Statements and semicolons

A statement is one instruction, and it ends with a semicolon ;. The semicolon, not the end of the line, ends a statement, so one statement can span several lines and several statements could share a line. Lines starting with #, function headers like int main(), and closing braces of functions don't take a semicolon.

return 0;

Ends main and reports the exit status: 0 means success, any other value means an error. Scripts and build tools use this value. In main only, you may leave it out and the compiler returns 0 for you, but writing it is clearer.

Output with std::cout

std::cout ("character output") writes to the console. The << operator, called the insertion operator, sends values to it, and you can chain as many as you like in one statement. Text goes in double quotes, single characters in single quotes, and numbers and variables are written as they are.

std::endl vs '\n'

Both end the line. The difference: std::endl also flushes the output buffer, which forces the text to be written immediately. Flushing is slow when done thousands of times, so prefer '\n' in normal code and use std::endl only when you need output to appear immediately.

Escape sequences

SequenceMeaning
\nNew line
\tTab
\"Double quote inside a string
\'Single quote
\\Backslash
\0Null character

Input with std::cin

std::cin ("character input") reads from the keyboard using the extraction operator >>:

#include <iostream>
#include <string>

int main()
{
    std::string city;
    int age;

    std::cout << "Enter your age: ";
    std::cin >> age;
    std::cout << "Enter your city: ";
    std::cin >> city;

    std::cout << "You are " << age << " years old and live in " << city << ".\n";
    return 0;
}

Typing 25 and Pune:

Console (typed input shown in the prompts)
Enter your age: 25
Enter your city: Pune
You are 25 years old and live in Pune.

Now type 25 and New Delhi:

Output (last line)
You are 25 years old and live in New.

"Delhi" disappeared. std::cin >> stops reading at the first space. To read a whole line, use std::getline. After reading a number with >>, the Enter key is still waiting in the input, so skip it first with std::cin.ignore():

std::cout << "Enter your age: ";
std::cin >> age;
std::cin.ignore();               // skip the Enter left after the number

std::cout << "Enter your city: ";
std::getline(std::cin, city);    // reads the whole line, spaces included
Output (last line)
You are 25 years old and live in New Delhi.

Try it yourself: run the program below. Change the input (age on the first line, city on the second), then try removing std::cin.ignore(); and run it again to see what happens.

Namespaces: std:: and using namespace std

The standard library puts all its names in a namespace called std, so they don't clash with names you create. That's why we write std::cout: "the cout that lives in std". :: is the scope resolution operator.

Forget the prefix and the compiler doesn't recognise the name. g++ even suggests the fix:

Compiler output
nostd.cpp: In function 'int main()':
nostd.cpp:5:5: error: 'cout' was not declared in this scope; did you mean 'std::cout'?
    5 |     cout << "Hello" << endl;
      |     ^~~~
      |     std::cout

Many tutorials add using namespace std; after the includes so they can write just cout:

#include <iostream>
using namespace std;   // fine for small learning programs

int main()
{
    cout << "No std:: prefix needed here" << endl;
    return 0;
}
Output
No std:: prefix needed here

It works, and you'll see it often. In real projects, and especially in header files, it's discouraged: it pulls hundreds of names into your code and can cause name clashes. This course uses std::, which is also what interviewers like to see.

Comments

// A single-line comment: everything after // is ignored

/* A multi-line comment
   can span several lines */

int total = 0;   // a comment can follow code on the same line

Comments are removed before compilation and don't make the program slower or bigger. Use them to explain why the code does something, not to repeat what the code obviously says. Multi-line comments can't be nested.

Other syntax rules

  • Case sensitive: main, Main and MAIN are different. Keywords are always lowercase.
  • Whitespace is free: spaces, tabs and blank lines are ignored (except inside strings), so indent for readability.
  • Identifiers (names) use letters, digits and _, can't start with a digit, and can't be keywords. Details in variables.
  • Strings use double quotes ("Hello"); a single character uses single quotes ('H').
  • File extensions: source files use .cpp (also .cc or .cxx), header files .h or .hpp.

Reading compiler errors

Compiler errors look scary, but they follow the same format: file:line:column: error: message. Always fix the first error first; later errors are often caused by it.

Missing semicolon

Compiler output
missing_semicolon.cpp: In function 'int main()':
missing_semicolon.cpp:5:50: error: expected ';' before 'return'
    5 |     std::cout << "Missing semicolon" << std::endl
      |                                                  ^
      |                                                  ;
    6 |     return 0;
      |     ~~~~~~

The compiler only notices the problem when it reaches the next statement (return), but it points exactly to where the ; belongs: line 5, column 50.

Wrong capitalisation

Compiler output
case.cpp: In function 'int main()':
case.cpp:6:18: error: 'Total' was not declared in this scope; did you mean 'total'?
    6 |     std::cout << Total << '\n';
      |                  ^~~~~
      |                  total

The variable was declared as total but used as Total. Because C++ is case sensitive, those are two different names.

Interview questions

Why does every C++ program need a main() function?

It's the entry point: the operating system starts the program by calling main. A program without it compiles into object code but fails at the link step.

What is the difference between std::endl and '\n'?

Both insert a newline; std::endl also flushes the output buffer. Use '\n' by default for performance.

Why is using namespace std considered bad practice?

It brings every name from std into the current scope, which can cause name conflicts and ambiguity, especially in header files included by other code. Prefer std:: or specific declarations like using std::cout;.

What is the difference between cin >> and getline?

cin >> reads one word and stops at whitespace; std::getline reads the whole line including spaces. After a cin >>, call cin.ignore() before getline to discard the leftover newline.

Summary

  • A program has includes, one main() function, a body in braces, and statements ending with ;.
  • std::cout << prints; std::cin >> reads a word; std::getline reads a line.
  • Prefer '\n' over std::endl, and std:: over using namespace std.
  • C++ is case sensitive and ignores extra whitespace.
  • Read compiler errors from the first one: file, line, column and message.

Next lesson: C++ variables: declaring, initialising and naming the data your program works with.