The C++ Programming Language Syntax


This programming tutorial focuses on the C++ programming language. On this page we introduce the C++ language grammer (syntax).

Statements and the End of Line Character
In the C++ programming language, a semicolon is a used to denote the end of a line. A single statement normally sits on a single line and ends with a semicolon. However, if the statement is very long, you can span it over two or more lines to make it more readable and easy to maintain. Whether a statement s on a single line or spans multiple lines, it must be terminated with a semicolon. You can have more than one statement on a line separated by a semicolon – but this is not advisable.

Whitespace
In order to make your code very readable and easy to maintain, make adequate use of whitespace. Whitespace does not contribute to the size of your programs, and is there for you to take advantage of.

Braces and Indentation
A block of code is enclosed in braces {}. Indentation helps you to easily identify to which code block code belongs. By combining braces and indentation, along with whitespace, you can make your life and the lives of fellow programmers much easy through writing very neat code. The rule of thumb is to indent code when it belongs to something, and indent when it doesn’t.

Comments
Comments are there for your benefit and not the compiler’s. The compiler simply discards comments, and they do not add to the size of your programs. There are two types of comments. These are single line comments that start with //, and multiple line comments enclosed within /* and */.

Variables
Variables are named value types whose names are fixed, but whose values can change over time. Variable names can only consist of letters, numbers, and underscores. A varable name can only start with an underscore or letter. Variable names cannot be the same as keywords and reserved words. Keywords and reserved words are reserved by the language for a purpose.

Case Sensitivity
C++ is case sensitive. So variableName is not the same as Variable Name.

Numeric Types
There are two numeric types in the C++ programming language. These are integers and floating-point numbers. Integers are whole numbers with no decimal place. Floating-point numbers contain decimal points. The C++ numeric types are:

Data Type Description Size in Bits Range of Values
char signed character or byte 8 -128 to 127
signed char signed character or byte 8 -128 to 127
unsigned char unsigned character or byte 8 0 to 255
long int signed integer 32 same as int
signed long int signed integer 32 same as int
int signed integer 32 -2,147,483,648 to 2,147,483,647
signed int signed integer 32 same as int
unsigned long int unsigned integer 32 same as unsigned int
unsigned int unsigned integer 32 0 to 4,294,967,295
short int signed short integer 16 -32,768 to 32,767
signed short int signed short integer 16 -32,768 to 32,767
unsigned short int unsigened short integer 16 0 to 65535
float single precision floating-point 32 1.8E-38 to 3.4E+38
double double precision floating-point 64 2.2E-308 to 1.8E+308
long double double precision floating-point 64 same as double
bool boolean 8 or 32 true or false

Overflow Errors
An overflow error occurs when you assign a large number that is too big for the variable’s type that it is assigned to.

Variable Declaration and Initialisation
You can declare variables without assigning a default value. Such as value is uninitialised. Using an unitialized variable will result in a compilation error. Once a variable has been declared it can be initialsed before use by assigning a value to it as the code below demonstrates.

int age; // Declared but unitialised.
age = 37; // The variable age has now been initialised.

It is also possible and good practice to declare and initialise variables with a default value as shown below. This way you can avoid the possibility of compile-time errors caused by using variables that have not been initialised.

// This variable is declared and initialised ready for use.
int age = 37;

Variables names can only contain the underscore, letters, and numbers. A variable’s name can start with an underscore or a letter, but it cannot start with a number.

REMEMBER: C++ is case sensitive. So the variable age is not the same as Age, and the variable reportName is not the same as ReportName. Exceptions caused by using the wrong case for variables that have already been declared is a common issue.

In the C++ programming language, there is no such variable type as a string. In order to declare and initialise strings you must create what’s known as a character array. Creating a character array is easy. However, you need to be careful of string termination.

Strings
As already stated, in order to declare a string you must use character arrays. The code below shows different ways in which you can declare and initialise character arrays.

// Declared and initialised simultaneously.
char reportName[] = "Weekly Staffing Forecast";
// Declared and initialised separately.
char fieldName[50];
fieldName = "DateOfBirth";

Strings are terminated with the null character. So the string DateOfBirth stored in the character array fieldName is actually 12 characters in size and not 11. The null terminator is placed at the end of a string in a character array and is a zero. You cannot see the null terminator or print it out, but it is there, and its purpose is to quickly identify the end of a string value. So if you want to declare a string of a known size, you would have to declare a character array of size known value plus 1 as in the example below.

char car[4] = "car";

Arrays
An array is a collection of multiple items of the same type. For instance, you can have arrays of characters as you have already seen, arrays of numeric types, and arrays of object types ect.

int oneDimensionalArray[20];
int twoDimensionalArray[20][10];
int threeDimensionalArray[20][10][5]
int fourDimensionalArray[40][30][20][10];
int tableArray[5][2] =
{ {0,0}, {1,2}, {2,4}, {3,6}, {4,8}};

The index of an array is the reference that points to a particular element of the array. All array indexes start at zero. So to access the first element of an array, you would type myArray[0].

Structures
A named collection of data types is called a structure. Structures can contain other structures and various different data types. The code below shows an example of a structure and its usage.

struct book
{
char[18] isbn;
char[14] barcode;
char[50] publisher;
char[50] title;
char[1000] decription;
char[50] author;
short int edition;
short int year;
float price;
};

books book[25];
book[0].isbn = "978-1-4302-2381-8";
book[0].barcode = "9781430223818";
book[0].publisher = "Apress";
book[0].title = "Pro Silverlight 3 in C#";
book[0].decription = "Silverlight is a revolutionary browser plu-in that allows ...";
book[0].author = "Matthew MacDonald";
book[0].edition = 1;
book[0].year = 2009;
book[0].price = 49.99;

The code above creates an array of 25 books. The first element in the array has an index of 0, and the last element in the array has an index of 25. In this example, the first book has been initialized with values.

A separate storage location is reserved for each variable contained with a structure. Structures keep track of all their variables. In our book example, the structure would reserve 9 memory locations.

Unions
A union is used in the same way that you use a structure. However, the main difference other than the keyword is in the way unions reserve memory. Regardless of how many variables are contained within a union, a union will only reserve one memory location that will be shared by each of the union’s variables. The size of a union is the sum of bytes needed to store all variables declared within the union. Unions only track one variable at a time.

If both variables are required to be used at the same time, it is best to use a structure. But if you want to conserve memory, or it is not necessary to use both variables at the same time, then your best choice will be a union.

union role
{
int id;
char[50] name;
char[255] description;
}

role admin = new role();
admin.id = 1;
admin.name = "Administrator";
admin.description = "This role contains full admin rights.";

typedef
Using typedef you can give a type a name. So for instance, you code give the name Administrator to the union role.

typedef role Administrator;

Administrator system_admin = new Administrator();
Administrator super_user = new Administrator();

Enums
An enumerated type (enum) is a collection of integer types whose values you can explicitly define, or if you do not define values, have the compiler define the values for you.

// Constants
const int SUNDAY = 0;
const int MONDAY = 1;
const int TUESDAY = 2;
const int WEDNESDAY = 3;
const int THURSDAY = 4;
const int FRIDAY = 5;
const int SATURDAY = 6;


// Using enumerated types you can re-write the above code
// as:

enum DaysOfWeek
{
SUNDAY
, MONDAY
, TUESDAY
, WEDNESDAY
, THURSDAY
, FRIDAY
, SATURDAY
}

// Or alternatively you could rewrite the above like
// this:

enum DaysOfWeek
{
SUNDAY = 0
, MONDAY = 1
, TUESDAY = 2
, WEDNESDAY = 3
, THURSDAY = 4
, FRIDAY = 5
, SATURDAY = 6
}

DaysOfWeek currentDay = THURSDAY;

Explicit and Implicit Casting
In C++ you can cast a one type to another type as long as the cast is valid. For example, you can cast an int to a short, a long to a float, and a float to a double. The cast operator is an open parenthesis followed by a type followed by a closing parenthesis.

// Declare and assign values to a float and double.
float boat = 10.1;
double vessel = 0;
// Cast the value of the float to a double,
// and assign the result to the double.
vessel = (double)boat;

When a small variable type is cast to a larger type which does not result in loss of precision (loss of accuracy), we promote the variable. And when we cast a large variable type to a smaller variable type that may result in a loss of precision, we demote the variable. So far we have seen explicit casting in which we explicitly tell the compiler to cast the value of one type to another. When promoting a variable we do not have to explicitly perform the cast. This is because promoting a variable does not result in loss of data. The compiler happily performs the cast for us. This is known as implicit casting.

Variable Scope
All variables have scope within the block of code that encloses them. The different scopes include global variables that are accessible throughout a program, and local variables are accessible only to the local code block that encloses them. You can have variables with different scopes but the same name. In this situation, the most local variable hides the other variables and is the one that is used. Class level variables are known as member variables, and are accessible within all constructors, methods, and properties of the class. Variables that are method parameters only exist for the lifetime of the method, and variables that are defined within or as part of a loop only exist within a that loop. Variables defined between matching braces only exist within the scope of those braces.

Program Flow
A computer program needs the ability to flow in a specific direction based on a specific condition. For example, when performing mathematical calculations the calculation will call into play operator precedence. Another example of program flow is repeating a process while a condition is true, etc. Operator precedence, loops, the if statement, and the switch/case statements are allways in which you can control the flow of a C++ computer program.

Operator Precedence
The table below provides a list of the C++ operators in order of execution. The items at the top of the list being executed first, and the items at the bottom being executed last.

Operator     Description
()     Grouping Operator
!     Logical Negation Operator
(type)     Cast Operator
.*     Member Object Selector
*     Multiplication Operator
/     Division Operator
+     Addition Operator
    Subtraction Operator
<     Less-than Operator
<=     Less-than-or-equal-to Operator
>     Greater-than Operator
>=     Greater-than-or-equal-to
==     Equal-to Operator
!=     Not-equal-to Operator
&&     Logical AND Operator
||     Logical OR Operator
=     Assignment Operator

To force operator precedence enclose the operations you want done first within the grouping operator.

NOTE: Using the grouping operator within calculations is very important. This way, you make your intent very clear to the compiler and to other programmers.

The While Loop
This loop only executes while a boolean test condition is true. If the boolean test condition is never true then this loop will never execute. On the other hand, this loop will execute an infinite loop and will never exit unless it encounters a break statement or error condition.

while(bool)
{
  // Code to execute within the loop.
}

The Do/While Loop
The do/while loop always executes at least once, and will continue to execute while the boolean test condition is true. The execution of the loop will be terminated upon the boolean test condition being false, a break statement being encountered, or an exception being raised.

do
{
  // Code to be executed.
}
while(true);

The break Statement
To exit a loop or switch statement use the break statement.

do
{
  break; // Terminates the loop.
}
while(true);

The continue Statement
To terminate the current iteration of loop and continue with the next iteration use the continue statement.

int counter = 0;
do
{
  counter = counter + 1;
  if (counter == 3)
    continue;
  cout << counter;
}
while(counter <= 9);

The if/else Statement
The if/else statement is ideal in situations where you want to do one thing when a test condition is true, and another thing when a test condition is false.

if (x == 1)
{
  // Do this when x = 1.
}
else if (x == 2)
{
  // Do this when x = 2.
}
else
{
  // In all other cases do this.
}

The switch/case Statement
The switch statement is very useful in branching code based on the value of an integer type. You pass in a valua that is an integer or that can be promoted to an integer, and have a number of case statements that do different things based on the value passed in. It is important to use the break statement in every case statement, otherwise every case statement will be executed sequentially. In the event that none of the case statements are encountered, you can use the default statement.

switch (move)
{
  case MOVE_LEFT:
    MoveLeft();
    break;
  case MOVE_RIGHT:
    MoveRight();
    break;
  case MOVE_UP:
    MoveUp();
    break;
  case MOVE_DOWN:
    MoveDown();
    break;
  default:
    InvalidMove();
    break;
}

Functions
A function is a named block of code enclosed within braces. Method signatures consist of access modifiers, a return type, parenthesis, and parameters contained within the parenthesis followed by braces. And example of a function is presented in the following code.

public static int Add(int x, int y)
{
  int z = x + y;
  return z;
}

Function Returns
If the return type for a function is void, then you do not need to include the optional return. For any other return type, it is mandatory to include the return keyword followed by a variable of the correct type.

Pass By Value
When passing a value into a parameter, the default behaviour is to pass by value. This means that the value being passed into the parameter is not changed outside of the function where the parameter is used. For example, if you have a function called testFunction that contains a variable called myInt, and you pass myInt into a function called testPassByValue, when testPassByValue finishes executing and returns control to testFunction, variable myInt still contains the value that it held before testPassByValue was called.

Reference Operator
You can create a reference variable that points to another variable by using the reference operator (&). The code below provides an example of the reference operator in action.

int originalVariable = 10;
int &referenceVariable = originalVariable;
referenceVariable = 37;
// originalVariable now equals 37;

Pass By Reference
A function affects a variable passed into it by reference. See the following code example.

int externalVariable = 37;
PassByReferenceMethod(externalVariable);
int PassByReferenceMethod(int &value)
{
  return (value + 10);
}
// externalValue = 47

Default Parameters
Default parameters, also known as optional parameters, are function parameters that are set to some default value. The only rule for using default parameters is that every parameter that follows a default parameter must be a default parameter itself. The code below demonstrates the use of default parameters.

void DefaultParameterFunction(int nonDefaultParameter, int defaultParameter = 10)
{
  // Do something here.
}

// Both of the following DefaultParameterFunction calls are valid.
DefaultParameterFunction(10);
DefaultParameterFunction(10, 25);

This article is still under construction.

Advertisements