C++ Notes: Basic topics

Posted on: September 7, 2022
8 min read

Statements

A computer program is a sequence of instructions that tell the computer what to do. A statement is a type of instruction that causes the program to perform some action.

Statements are by far the most common type of instruction in a C++ program. This is because they are the smallest independent unit of computation in the C++ language. In that regard, they act much like sentences do in natural language. Most (but not all) statements in C++ end in a semicolon.

There are many different kinds of statements in C++:

  • Declaration statements
  • Jump statements
  • Expression statements
  • Compound statements
  • Selection statements (conditionals)
  • Iteration statements (loops)
  • Try blocks

Comments

A comment is a programmer-readable note that is inserted directly into the source code of the program. Comments are ignored by the compiler and are for the programmer’s use only.

Single-line comments

The // symbol begins a C++ single-line comment, which tells the compiler to ignore everything from the // symbol to the end of the line. For example:

std::cout << "Hello world!"; // Everything from here to the end of the line is ignored

// std::cout lives in the iostream library
std::cout << "Hello world!\n";

Multi-line comments

/* This is a multi-line comment.
   This line will be ignored.
   So will this one. */

Data and values

Data is any information that can be moved, processed, or stored by a computer. A single piece of data is called a value. Common examples of values include letters (e.g. a), numbers (e.g. 5), and text (e.g. Hello).

Objects and variables

In C++, direct memory access is discouraged. Instead, we access memory indirectly through an object. An object is a region of storage (usually memory) that can store a value, and has other associated properties. Although objects in C++ can be unnamed (anonymous), more often we name our objects using an identifier. An object with a name is called a variable.

In order to create a variable, we use a statement called a definition statement. When the program is run, each defined variable is instantiated, which means it is assigned a memory address.

Initialization can be used to give a variable a value at the point of creation. C++ supports 3 types of initialization:

  • Copy initialization.
  • Direct initialization (also called parenthesis initialization).
  • List initialization (also called uniform initialization or brace initialization).
int a;         // no initializer (default initialization)
int b = 5;     // initializer after equals sign (copy initialization)
int c( 6 );    // initializer in parenthesis (direct initialization)

// List initialization methods (C++11) (preferred)
int d { 7 };   // initializer in braces (direct list initialization)
int e = { 8 }; // initializer in braces after equals sign (copy list initialization)
int f {};      // initializer is empty braces (value initialization)

Literals

A literal (also known as a literal constant) is a fixed value that has been inserted directly into the source code. Examples are 5 and “Hello world!”.

std::cout << "Hello world!";
int x { 5 };

Operators

An operation is a process involving zero or more input values, called operands. The specific operation to be performed is denoted by the provided operator. The result of an operation produces an output value.

  • Unary operators act on one operand. An example of a unary operator is the - operator.
  • Binary operators take two operands, often called left and right. An example of a binary operator is the + operator.
  • Ternary operators take three operands. There is only one of these in C++ (the conditional operator).
  • Nullary operators take zero operands. There is also only one of these in C++ (the throw operator).

Expressions

An expression is a combination of literals, variables, operators, and function calls that are evaluated to produce a single output value. The calculation of this output value is called evaluation. The value produced is the result of the expression.

2               // 2 is a literal that evaluates to value 2
"Hello world!"  // "Hello world!" is a literal that evaluates to text "Hello world!"
x               // x is a variable that evaluates to the value of x
2 + 3           // operator+ uses operands 2 and 3 to evaluate to value 5
five()          // evaluates to the return value of function five()

An expression statement is an expression that has been turned into a statement by placing a semicolon at the end of the expression.

Functions

In C++, statements are typically grouped into units called functions. A function is a collection of statements that get executed sequentially (in order, from top to bottom). A function call is an expression that tells the CPU to execute a function. The function initiating the function call is the caller, and the function being called is the callee or called function. Do not forget to include parenthesis when making a function call.

#include <iostream>

int main() {
  std::cout << "Hello world!";
  return 0;
}

Return values

A function that returns a value is called a value-returning function. The return type of a function indicates the type of value that the function will return. The return statement determines the specific return value that is returned to the caller. A return value is copied from the function back to the caller — this process is called return by value. Failure to return a value from a non-void function will result in undefined behavior.

The return value from function main is called a status code, and it tells the operating system (and any other programs that called yours) whether your program executed successfully or not. By consensus a return value of 0 means success, and a non-zero return value means failure.

Functions with a return type of void do not return a value to the caller. A function that does not return a value is called a void function or non-value returning function. Void functions can’t be called where a value is required.

Parameters and Arguments

A function parameter is a variable used in a function where the value is provided by the caller of the function. An argument is the specific value passed from the caller to the function. When an argument is copied into the parameter, this is called pass by value.

Function parameters and variables defined inside the function body are called local variables. The time in which a variable exists is called its lifetime. Variables are created and destroyed at runtime, which is when the program is running. A variable’s scope determines where it can be seen and used. When a variable can be seen and used, we say it is in scope. When it can not be seen, it can not be used, and we say it is out of scope. Scope is a compile-time property, meaning it is enforced at compile time.

Forward declarations and definitions

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. To write a forward declaration for a function, we use a function prototype, which includes the function’s return type, name, and parameters, but no function body, followed by a semicolon.

A definition actually implements (for functions and types) or instantiates (for variables) an identifier. A declaration is a statement that tells the compiler about the existence of the identifier. In C++, all definitions serve as declarations. Pure declarations are declarations that are not also definitions (such as function prototypes).

#include <iostream>

// forward declaration of add() (using a function declaration)
int add(int x, int y);

int main() {
  // this works because we forward declared add() above
  std::cout << "The sum of 3 and 4 is: " << add(3, 4) << '\n';
  return 0;
}

// even though the body of add() isn't defined until here
int add(int x, int y) {
  return x + y;
}

Multiple files

Most non-trivial programs contain multiple files.

When two identifiers are introduced into the same program in a way that the compiler or linker can’t tell them apart, the compiler or linker will error due to a naming collision. A namespace guarantees that all identifiers within the namespace are unique. The std namespace is one such namespace.

The preprocessor is a process that runs on the code before it is compiled. Directives are special instructions to the preprocessor. Directives start with a # symbol and end with a newline. A macro is a rule that defines how input text is converted to a replacement output text.

Header files are files designed to propagate declarations to code files. When using the #include directive, the #include directive is replaced by the contents of the included file. When including headers, use angled brackets when including system headers (e.g. those in the C++ standard library), and use double quotes when including user-defined headers (the ones you write). When including system headers, include the versions with no .h extension if they exist.

Header guards prevent the contents of a header from being included more than once into a given code file. They do not prevent the contents of a header from being included into multiple different code files.

cpp