Skip to content

Basic Syntax & Types

In this chapter, we will explore the building blocks of C++: variables, types, and how to manage data.

Comments

Comments are ignored by the compiler but are crucial for code readability.

1
2
3
4
5
6
// This is a single-line comment

/*
   This is a multi-line comment.
   It can span multiple lines.
*/

Doxygen Style

For documentation generation, use /// or /** ... */.

1
2
3
4
5
/// Calculates the sum of two integers.
/// @param a First integer
/// @param b Second integer
/// @return Sum of a and b
int add(int a, int b);

Variables and Initialization

A variable is a named storage location in memory. In Modern C++, we strongly recommend using Uniform Initialization (brace initialization).

Why Uniform Initialization?

It prevents "narrowing conversions" (accidental data loss) and is consistent across all types.

1
2
3
4
5
6
int a = 10;     // C-style assignment
int b(10);      // Constructor style
int c { 10 };   // Modern Uniform Initialization (Preferred)

// int d { 3.14 }; // Error! Prevents narrowing double to int
int e = 3.14;   // Compiles but truncates to 3 (Warning)

Type Deduction (auto)

The auto keyword lets the compiler deduce the type from the initializer. This guarantees initialization and avoids type mismatches.

1
2
3
4
auto count = 10;        // int
auto voltage = 3.3;     // double
auto name = "Raspberry"; // const char*
auto is_ready = true;   // bool

Fundamental Types

C++ provides a rich set of built-in types. On a 64-bit Raspberry Pi (ARM64), typical sizes are:

Integer Types

Type Size Range (Approx) Description
int 4 bytes ±2 Billion Standard integer
short 2 bytes ±32,768 Small integer
long 8 bytes ±9 Quintillion Large integer (64-bit)
long long 8 bytes ±9 Quintillion Guaranteed at least 64-bit

Unsigned Types: Adding unsigned shifts the range to start at 0 (e.g., unsigned int is 0 to 4 Billion).

Floating-Point Types

Type Size Precision Description
float 4 bytes ~7 digits Single precision
double 8 bytes ~15 digits Double precision (Default)

Other Types

  • bool: Represents truth values (true or false). Size is usually 1 byte.
  • char: A single character (ASCII). 1 byte.
  • void: Represents the absence of a type (used for functions returning nothing).

Literals

Literals are fixed values written directly in code.

  • Integer: 42, 0xFF (Hex), 0b1010 (Binary), 100L (Long), 10u (Unsigned).
  • Floating-point: 3.14, 1.0f (Float), 2.5e-3 (Scientific).
  • Character: 'A', '\n' (Newline).
  • String: "Hello", u8"UTF-8 String".
  • Boolean: true, false.
  • Pointer: nullptr (Modern null pointer).

Constants: const vs constexpr

Immutability is key for robust software.

  • const: "I promise not to change this." Checked at compile-time, but value might be determined at runtime.
  • constexpr: "This value is known at compile-time." Crucial for performance and template metaprogramming.
1
2
3
4
int x;
std::cin >> x;
const int limit = x * 2;    // Runtime constant
constexpr int buffer_size = 1024; // Compile-time constant

Scope and Lifetimes

Variables have a scope (where they are visible) and a lifetime (when they exist in memory).

Local Scope (Block Scope)

Variables declared inside { ... } exist only within that block.

1
2
3
4
5
6
7
8
9
int main() {
    int x = 10;
    {
        int y = 20;
        std::cout << x << " " << y; // OK
    }
    // std::cout << y; // Error: y is out of scope
    return 0;
}

Global Scope

Variables declared outside any function. Avoid them if possible, as they make code hard to debug.

Type Conversion (Casting)

Sometimes you need to convert between types.

  • Implicit: Automatic (e.g., int to double).
  • Explicit (static_cast): The safe, modern way to cast.
double pi = 3.14159;
int approx = static_cast<int>(pi); // Explicitly convert to int (3)

Avoid C-style casts like (int)pi.