# C++ Syntax

This page is a reference for C++ syntax that corresponds to topic coverage for CS 135 and CS 202. Disclaimer: The topics are arranged to mirror the chronological order that they are covered in for those two courses, but note that each instructor may cover topics in a different order, not cover topics listed here, or cover topics that are not listed here.

# CS 135 Topics

  • Hello World
  • Comments/Commenting
  • Basic Data Types
  • Variables, expressions, and operators

# Hello World

A typical first program in many programming languages is called hello world and refers to a basic program that is only designed to display text to the screen. This program is meant to be used to illustrate some of the basic features of a programming language, such as syntax and style. The terms program, source code, and code can be used interchangeably.

For C++, the hello world program is as follows:

// This is a Hello World Program    // Line 1
#include <iostream>                 // Line 2
                                    // Line 3
using namespace std;                // Line 4
                                    // Line 5
int main()                          // Line 6
{                                   // Line 7
    cout << "Hello World!" << endl; // Line 8
                                    // Line 9
    return 0;                       // Line 10
}                                   // Line 11

The following is a brief description of what each line is used for:

  • Line 1: Lines that start with // are comments and are not technically part of the program but are often written to describe the code or insert other useful information such as the author.
  • Line 2: This is a preprocessor directive that includes the header file iostream which we need to use cout and endl on line 6.
  • Line 3: This is a blank line which is used to improve code readability.
  • Line 4: This is a line that makes it easier to use commands in the standard namespace. This will be described in more detail later, but for now just know that it should be part of most programs that you write.
  • Line 5: Another blank line used to improve code readability.
  • Line 6: int main() is the definition of the main body (or main function) that describes where the program actually starts. Every C++ program contains this function. int refers to the fact that this function should return an integer to end it.
  • Line 7: { signifies the beginning of the main body block.
  • Line 8: This is a statement. Note that this code is indented. This is not technically required but improves code readability. Further details about this line are as follows:
    • cout is used to display output to the terminal
    • << is used to separate various things that will be displayed
    • "Hello world!" is a string
    • endl is used to end the line on the output, going to the next line on the display
    • ; is used to signify the end of the statement.
  • Line 9: Another blank line used to improve code readability.
  • Line 10: return 0; is the final line of the main body and returns an integer (in this case, 0) that matches line 6.
  • Line 11: } signifies the end of the main body. Note that this lines up in the same column as line 7.

Note: Programs do not contain actual line numbers as shown above unless working in certain IDEs; the addition of line numbers has been added for your convenience.

# Comments / Commenting

Syntactically, comments in C++ can be accomplished in two ways:

  • Single Line Comments are prefaced by // and end at the end of the line they are placed on
  • Multi-line Comments are placed between /* and */ and can span over multiple lines
// This is a single line comment

This is not a comment     // but this is

cout << "Hi!" << endl;    // This is a comment but the cout statement is not a comment

/* This is also technically a single line comment but using the multi-line comment format */

/* Everything
   in
   here
   is a comment */

cout << "Hi!" << endl;    // This is a single line 
cout << "Hi!" << endl;    //  comment format but 
cout << "Hi!" << endl;    //  spanning over 
cout << "Hi!" << endl;    //  multiple lines.

cout << "Hi 1" << endl;    /* This multi-line comment actually
cout << "Hi 2" << endl;        ends up removing the last three
cout << "Hi 3" << endl;        cout statements and therefore 
cout << "Hi 4" << endl;        only "Hi 1" will be displayed. */

It is common to use comments in programs:

  • At the top of your source code to provide your name, class, section number, and a program description
  • Throughout the code when necessary to explain functions and particularly complicated algorithms
  • When trying to leave out code because it is partially written or 'buggy' -- commonly called commenting out the code

For additional details on comments, visit the external reference page here (opens new window).

# Basic Data Types

C++ contains many data types, the basic data types (also called fundamental or primitive) are those whicha re built into the core language. More complex data types are typically built upon the foundation of these basic data types.

The most common basic data types are int, double, char, and bool.

  • int

    • The int data type is used for representing positive and negative integers (whole numbers). Typically an int uses 4 bytes (32 bits) of storage. The first bit of an int is used for the sign (positive or negative) and the remaining 31 bits are used to encode the integer in binary. Thys, the typical range for an int is -231 to 231- 1. Note that the positive range is one less than the negative because the representation of zero is included in the positive numbersbut there is no "negative zero".
  • double

    • The double data type is used for representing real numbers. It typically uses 8 bytes (64 bits) and encodes the value in three parts:

      • 1 bit for a sign (e.g. Negative)
      • 11 bits for an exponent (e.g. 125)
      • 52 bits for a mantissa (e.g. 5.883)
    • The value is then given as: sign mantissa x 10exponent. The major advantage of using a double is that it can store a very large range of values (up to 10308), but it only contains 15 decimal place accuracy. For example, a number consisting of the digit 2 repeated many times may be written as 2.2222... 2 x 10300, but when encoded, everything after the 15th digit is lost, so the actual representation would be 22222222222222200000......0.

  • char

    • The char (pronounced like char in charbroil) data type is used for representing characters. It typically uses 1 byte (8 bits) and encodes the character according to the ASCII Table (opens new window). Note that ASCII only contains 128 values (range 0 to 127), although 1 byte can encode 256 different values. The values outside of the range 0 to 127 are not standardized and rarely used.

    In C++ when explicitly using characters, they must be enclosed in single quotes:

    char ch;
    
    ch = 'A'; // The character A (ASCII value 65) is stored in ch
    ch = A;   // This is an error, unless A is another variable or constant
    
    cout << 'X' << endl; // Displays the character X
    cout << X << endl;   // This is an error, unless X is another variable or constant
    

    Note: The ASCII Table contains collated sequences of digits and letters, so 'B' + 3 is equal to 'E' for example.

  • bool

    • The bool data type is used for storing true/false Boolean values. It only needs 1 bit (0 or 1) but, as the smallest amount of addressable memory is 1 byte, it takes 1 byte of storage. The value of true is encoded as 1, while false is encoded as 0.
    bool z = true;
    
    z = false;
    
    if (z)
        cout << "The value of z was true" << endl;     // This line will not display
    else
        cout << "The value of z was false" << endl;    // This line will display
    
  • Modifiers

    • Various modifiers exist to change the usage of bits, thus changing the range. Some details are provided below:
      • short - less storage, less range than basic data type
      • long - more storage, more range than basic data type
      • long long - more storage, more range than the long data type
      • unsigned - uses sign bit for value representation, making the range span positive values only
      • signed - uses sign bit for sign representation, making the range span positive and negative values
  • Other Basic Data Types

    • In addition to the data types given above, there are data types of float (a smaller and less precise version of double) and three different character types: wchar_t, char16_t, and char32_t which use more than 1 byte of storage for characters.

Note: For an external link on more technical details on basic data types in C++, click here (opens new window).

# Variables, Expressions and Operators

Variables in C++ are used for storing values which are usually input, manipulated, and output. Variables must be explicitly declared as a specific data type (e.g. basic data types) before usage.

  • Identifiers

    • As in regular mathematics, variables have a name that we call an identifier in C++. Identifiers have various rules and conventions.

    • Identifer Rules

      • Identifiers must adhere to the following rules.
        • May only contain alphabetic characters, digits, and underscores
        • May not contain any special characters or spaces
        • May not start with a digit
        • May not be a reserved word
        • May not be identical to other identifiers in the same scope
    • Identifier Conventions

      • Although the following are all legal, identifiers should typically...
        • Not start with an underscore (these are frequently used for header files)
        • Not be all capital letters, unless used as a constant
        • Be descriptive about what is to be stored in them to help with code readability

    Note: identifiers, may, additionally, adhere to one of the many established naming conventions (opens new window).

  • Declaration

    • A variable can be declared as: datatype identifier;
    • Multiple variables can be declared in one line, for example int x, y, z;
  • Expressions

    • An expression is any combination of values, variables, and operators that can be evaluated. The following are all examples of expressions:
5 + 6
5 + 8 * 8
8 / 4.1 + 6 * 3
x               // assuming x is a declared variable
x + 5
"Hello"
'A'
'A' + 5
  • Assignment
    • Variables can be assigned the value of an expression if that expression can be evaluated to the same data type as the variable. Some examples are provided below.
int x = 5, y;

y = x * 2;

x = y;

x = 50;

x = 50 + (y + x) * 2;

Note that assignment is associative, so a = b = 5; will assign the value of 5 to both variables. Also note that assignment is an expression and evaluates to the variable itself, but it must be placed in parentheses. For example cout << (x = 5 + 6); will both output 11 and assign it to the variable x.

  • Initialization
    • Variables can be initialized upon declaration or their values can be set later (directly or via input). Variables should always have some value placed in them before they are used in any calculations or output, otherwise erroneous results may occur.
int age = 30; // Initialization upon declaration

double rate;
rate = 0.05; // Not initialization, but a valid method for placing a value in the variable before it is used in a calculation

double fee;
cin >> fee; // Not initialization, but a valid method for placing a value in the variable before it is used in a calculation
  • Mathematical Operations

    • Standard mathematical operations for integral and floating-point values are + - * / %.
    • The modulo operator, %, is the remainder when an integral value is divided by another, for example 10 mod 3 = 1, 100 mod 8 = 4, and 20 mod 5 = 0.
    • The order of operations is similar to regular mathematics, where multiplication and division are evaluated before addition and subtraction. The modulo operator is at the same precedence level as multiplication and division.
    • To enforce an alternate order of operations, parentheses can be used as in regular mathematics, for example 2 + 3 * 5 = 17 but (2 + 3) * 5 = 25.
  • Mixed Expressions

    • A mixed expression is an expression that contains both integral and floating-point data types. The general rule for evaluation is that operators of the same data type evaluate to a result of the same data type, while mixed expressions implicitly convert (or cast) integral values to floating-point values first. Some examples are provided below:
3.0 / 4.0 = 0.75   // both operands are floating-point, the result is floating point
3 / 4 = 0          // both operands are integral, the result is integral -- it is truncated, not rounded
3.0 / 4 = 0.75     // the integral operand is converted to 4.0 and the result is floating-point
3 / 4.0 = 0.75     // the integral operand is converted to 4.0 and the result is floating-point
  • Typecasting
    • Explicit conversion from one data type to another can be done using typecasting. There are several ways of typecasting:
      • Functional cast: datatype(expression)
      • C-style cast: (datatype)expression
      • Static cast: static_cast<datatype>(expression)

For example:

double d = 5.84;
int i;

// all 3 of the below assign the value of 5 to i (it is truncated, not rounded)
i = static_cast<int>(d); 
i = int(d);   
i = (int)d;

The standard way of doing typcasting in C++ is with static_cast.

  • Constants
    • Constants can be created by putting the const keyword in front of the datatype. A constant can be initialized but never changed after that. It is standard to use all capital letters for constant identifiers.
const int DRINKING_AGE = 21;
const double GOLDEN_RATIO = 1.618;
const double PI = 3.14;
  • Combined Assignment Operators
    • There are combined assignment operators for each of the five mathematical operations as described below:
x += expr;     // equivalent to x = x + (expr);
x -= expr;     // equivalent to x = x - (expr);
x *= expr;     // equivalent to x = x * (expr);
x /= expr;     // equivalent to x = x / (expr);
x %= expr;     // equivalent to x = x % (expr);
  • Increment / Decrement
    • Because operations such as adding 1 to a variable are common, instead of doing x = x + 1; or x += 1; there are unary operators for incrementing and decrementing values.
x++; // equivalent to x = x + 1; and x += 1;

x--; // equivalent to x = x - 1; and x -= 1;

# CS 202 Topics

Topics that may have received little coverage in CS 135 but are covered in chapters 1-9.

  • Switch Statements
  • continue and break
  • assert
  • Ternary Operator
  • Function Overloading
  • Default Function Parameters
  • Static Variables
  • enum
  • typedef
  • C-Strings
  • Multidimensional Arrays
  • istringstream (Note: Not in the textbook)
  • Command Line Arguments (Note: Not in the textbook)

# Switch Statements

switch and case are a pair of commands built into C++ (and many other programming languages) that operate similar to the if statement. An ideal situation to use them is when there is a sufficiently large number of finite options, for example a text-based menu with valid options of 1, 2, 3, 4 and 5.

switch can only be used with expressions that evaluate to integers, such as a logical comparison (result is 0 or 1), a char, or any non-floating-point expression.

The following code illustrates how switch and case work:

int x;

cin >> x;

if (x == 1)    
{
     statement1;
     statement2;
}
else if (x == 2)
{
     statement3;
     statement4;
}
else
{
     statement5;
     statement6;
}

switch (x)          // switch version (equivalent to above)
{
     case 1: 
             statement1;
             statement2;
             break;
     case 2: 
             statement3;
             statement4;
             break;
     default: 
             statement5;
             statement6;
}

Additional Notes:

  • If break is not placed after the statement(s) for one case, the statements in the following case will execute.
  • There is no requirement for a default section, althought one may be helpful.
  • There may be scope issues regarding declaring variables inside a case, in which case the declaration (and associated statements) can be enclosed in { }.

# continue and break

continue and break can be used to alter how loops run. break exits the loop immediately, while continue skips the remainder of the statements and restarts it.

for (int i = 0; i < 10; i++)   // Prints out the values 0 through 9
     cout << i << endl;

for (int i = 0; i < 10; i++)   // Prints out the values 0 through 5
{
     if (i == 6)
          break;

     cout << i << endl;
}

for (int i = 0; i < 10; i++)   // Prints out the values 0 through 4 and 6 through 9
{
     if (i == 5)
          continue;

     cout << i << endl;
}

# assert

assert is a function in the cassert header file that enables immediate termination of a program if an expression evaluates to false. It can be used to exit from a program at any point, even inside a function.

The following code...

#include <iostream>
#include <cassert>

using namespace std;

int main()
{
     cout << "Enter numerator: ";
     double numerator;
     cin >> numerator;

     cout << "Enter denominator: ";
     double denominator;
     cin >> denominator;

     assert(denominator != 0);

     cout << "Result is: " << numerator / denominator << endl;

     return 0;
}

Would have the output:

Enter numerator: 5
Enter denominator: 0
a.out: assert.cpp:16: int main(): Assertion `denominator != 0' failed.
Aborted

# Ternary Operator

The ternary operator ?: in C++ is the only operator that takes three operands and works similar to an if statement. It must be used carefully, and can lead to obfuscated code.

a ? b : c is equivalent to if (a) b else c.

int kids;

cin >> kids;

// using if statement
cout << "You have " << kids << " child";
if (kids != 1)
     cout << "ren";
cout << endl;

// using ternary operator
cout << "You have " << kids << " child" << ((kids != 1) ? "ren" : "") << endl;

The above code uses the ternary operator to accurately output 0 children, 1 child, 2 children, 3 children, etc.

# Function Overloading

Function Overloading is a form of polymorphism (identical symbols doing different things in context) in which multiple functions with the same name can be written, subject to certain restrictions. The primary restriction is that functions can be overloaded only if there is not a matching function that takes the same number of and type of parameters.

// Given the following function (stated as a prototype)
int fcn(int, int);

// The following functions can be written in the same program:
int fcn(int);
int fcn(int, int, int);
int fcn();
int fcn(double, int);
int fcn(int, double);

// The following functions cannot be written in the same program:
int fcn(int, int);
double fcn (int, int);
void fcn(int, int);

# Default Function Parameters

Functions that take parameters can also set default values for those parameters that are used if that parameter is not specified.

Rules:

  • You should specify the default parameters in the function prototype, not in the function definition -- otherwise you may get compiler errors
  • Once one parameter has a default value, the remaining parameters (on the right) must also have default parameters
  • When calling the function you must provide parameters for all non-default parameters
  • When you call a function in such a way that a default parameter is used, all remaining default parameters (on the right) must also be used
int fcn(int, int, int = 3, int = 4, int = 5);

int fcn(int a, int b, int c, int d, int e)
{
     return a + b + c + d + e;
}

// The following function calls are valid and return the value given below
fcn(10, 20)                returns 42
fcn(10, 20, 30)            returns 69
fcn(10, 20, 30, 40)        returns 105
fcn(10, 20, 30, 40, 50)    returns 150

// The following function calls are not valid
fcn()
fcn(10);
fcn(10, 20, , 40, 50);

The static keyword has other uses in C++, especially related to classes.

# enum

enum can be used to create and enumerated type, which is a datatype in which constants can be named and values are automatically assigned.

If the bool data type did not exist in C++, one could be created and used as follows:

#include <iostream>

enum bool {false, true};
// false is automatically assigned the value 0
// true is automatically assigned the next integral value after false, which is 1

using namespace std;

int main()
{
     bool var = false;

     var = true;

     if (var)
          cout << "This statement will always print" << endl;

     return (0);
}

The datatype can, like structs, be declared globally.

Additional Notes:

  • Each identifier in the list of constants must adhere to standard identifier rules
  • The identifier for the data type name must adhere to standard identifier rules
  • Individual constant identifiers can be set equal to specific values and, if this is done, later identifiers without explicit assignments take on the previous identifier's value plus 1 (e.g. with enum mytype {first = 5, second};, second is assigned a value of 6)
  • For much more information, see here (opens new window).

# Typedef

typedef can be used to rename a data type. The last identifier is the renamed data type, while everything between typedef and it is what it can be used in place of.

typedef unsigned long int myint;

// The following two variable declarations are equivalent given the above typedef
unsigned long int x;
myint x;

typedef statements can be made global.

# C-strings

C-strings are char arrays that end in the null terminator (NULL, 0 or '\0'). Pre-defined functions in C and C++ contain logic such that, even if a character array is very large, processing of that array stops when the null terminator is reached.

To convert a C++ string into a C-string, use the string.c_str() function.

# Multidimensional Arrays

Multidimensional arrays in C++ are no more complicated than one-dimensional arrays. Note the following:

int a;          // here, a is how to access one integer
int a[10];      // now, a[0] through a[9] are how to access the elements "inside" a


int b[10];      // here, b[0] is how to access one integer
int b[10][10];  // now, b[0][0] through b[0][9] are how to access the elements "inside" b[0]

Iterating through a two-dimensional array is accomplished by nesting loops:

int a[10];

for (int i = 0; i < 10; i++)
     a[i] = somevalue;



int b[3][5];

for (int i = 0; i < 3; i++)
     for (int j = 0; j < 5; j++)
          b[i][j] = somevalue;

The concepts described above for two-dimensional arrays apply to higher dimensional arrays as well.

# istringstream

istringstream can be used to turn any string into a stream. This can be useful for parsing string using the extraction operator >> or the getline function.

To use istringstream you must #include <sstream>.

This code snippet will output 15, 25, and 35 on separate lines:

string s = "10 20 30";

istringstream iss(s);

while (iss)
{
     int x;
     iss >> x;
     cout << "Result: " << x + 5 << endl;
}

Note that using istringstream to convert a single value to a numerical format is overkill, and instead functions like stoi or stod should be used instead.

# Command Line Arguments

Command line arguments in C++ are a method of passing values to a program at the time of execution.

To use command line arguments, your main body should be defined such that it accepts two parameters:

  • An integer value, typically called argc (argument count), which denotes the number of arguments (including the command used to execute the program)
  • An array of C-strings, typically called argv (argument vector), which contains the arguments
int main(int argc, char **argv)
// int main (int argc, char *argv[]) is another way to write this
{
     for (int i = 0; i < argc; i++)
          cout << argv[i] << endl;
}

This program will print out the command used to run the program (stored in the C-string argv[0]), and all command line arguments which are stored in the C-strings argv[1] to argv[argc - 1].