We will be using the
g++ compiler throughout
The most basic program written in C is shown below, with annotations:
To compile the program, we use the following commands in terminal:
Here is a quick run-down of the syntax:
To comment code, i.e. blocks of text which are to be ignored by the compiler, use
Get into the habit of commenting your code while you write it. Just do it!
Variables are case-sensitive. A variable declaration looks like:
<datatype>specifies what type of variable it is, and is one of
<identifier>is the name of the variable
[= <value>]is an optional parameter which can set a value to the variable
To use strings in your code, use the following syntax:
Be sure to include the
<string> library in the head of your file.
Use arrays to store data of the same type. Use the schema:
Remember that indexes in arrays start at zero. The size of the array must be fixed at compile time.
To set a value into an array:
To get a value from an array:
There are two types of operators:
The main operators are:
+ - * / %
+= -= *= /=
== != > < >= <=
! && ||
Take note that
double half = 1/2; returns zero as it is performing integer arithmetic. When defining a
double, use a decimal point:
double half = 1.0/2.0;.
We use the stream operators
>> to pass and receive data from the terminal. To print to the terminal, use:
To read input from the terminal, use
When printing to the terminal, it is good practice to format your output into columns. To do this, use the
std::cout.width() command, for example:
To read command line arguments, passed to the executable via the terminal, add extra parameters to the
The usual conditional structures are available in C++
Again, the usual iterative structures are available.
The schema for a function is as follows:
Be sure to prototype the function if your function definitions are positioned after the
The additional datatype
void can be given to a function if it does not return anything.
Place an ampersand
& before a parameter name of a function to pass the value by reference, rather than value. More on this in the Pointers section later.
Note that arrays passed to functions are passed by reference by default.
Dynamic arrays allocate memory for an array at run-time, rather than compile time. Use the schema:
Note that the size does not have to be specified at compile time. Be sure to check that allocation of memory was successful, and delete the array when it is no longer required.
There are several functions available in the
<fstream> library which allow for reading and writing text files.
std::ifstream- file input
std::ofstream- file output
std::fstream- both file input and output
The following code gives an example on how to write to a file:
The following code gives an example on how to read a file:
There are various file access modes which can be specified to ensure files are used properly. Seperate multiple modes with the pipe
std::ios::in- file is for input only
std::ios::out- file is for output only
std::ios::binary- file is formatted as binary
std::ios::ate- file is opened with the initial position at the end of the file
std::ios::app- append data to the end of the file if it already exists
std::ios::trunc- delete the file and start afresh if the file already exists
STL stands for Standard Template Library, and is a collection of templated containers and associated algorithms for manipulating those containers. Each container is a C++ class. For example, the
<vector> (templated) class:
Instances of the
<vector> object can be created in various ways, including the example above. Others include:
<vector> class has many member functions:
An iterators is an object which marks a position in a container object and allows such a container to be traversed. Each STL container can use iterators to access its contents. An iterator is specific to the type of container it is associated with. An iterator for a
std::vector< double > would be declared as
They can be dereferenced to access the value at the position they mark, either as
end() member functions return an iterator marking the beginning and end of the vector, respectively. There are several member functions to note:
Templates allows for generalisation of routines or classes to many data types, usually reducing code size.
T is an alias for a datatype which is specified when we call the routine:
A class is a programming construct which encapsulates and manipulates data. An instance of a class is called an object which has real memory allocated to it.
Encapsulation can be achieved via various access specifiers:
All members are publicly accessible from outside the class.
class keyword and place statements within curly braces. Remember to put a semi-colon at the end of the definition! For example:
By setting member variables to be private, and provide public getter and setter methods, we can validate the input to ensure data integrity. Member functions are defined outside the class construct, and we precede them with the class name and scope operator.
A constructor is called when a class is first instantiated, always has the same name as the class, and has a return type of
void. Constructors may, for example, initialise data members to a suitable initial value, and/or allocate any dynamic memory.
There are two special constructors:
Initialisation lists are a more efficient way of setting the starting values for member variables in an object.
Use the dot operator to call and access member functions of a class. For example,
Inheritance allows the creation of classes which are derived from other classes – they become a specialisation of another class. The specialised class is called the derived class. The class from which it inherits is called the base class.
A derived class extends the functionality of a base class. All members of the base class which are public or protected are available in the derived class. Additional members can be added to the derived class to extend the functionality of the base class.
Note that the access specifier can only be
private. The constructor of the derived class can only initialise members which the derived class can access. A derived class could never initialise private members of the base class. Thus, we must use the constructor of the base class to initialise those members.
Operator overloading is the definition of standard operators in the context of a class. Depending on the function of the class, most operators can be overloaded so that they make sense for the class. Such as overloading the
+ operator for the Vector class to perform component-wise vector addition. Use the following schema to overload an operator:
<class>is the name of the class
operator<sign>specifies which operator is being overloaded
<operand>specifies the second operand in the case of binary operators
For example, here is how to overload the
== operator to test if two
Points are equal
Then to use this overloaded operator:
When overloading the assignment
= operator ensure to return a reference to the original object:
This means we can do this:
Be careful, when overloading the assignment operator, not to perform self-assignment. Check first that the memory address of the operand
source is not the same as that of
We have seen we can do this:
However, we can define an operator on classes outside a class:
static members are variables or routines which are shared among all instances of a class. There is only one unique copy.
staticvariables can be thought of as global variables
staticclass member cannot be initialised more than once, so it is not initialised in a constructor of a class. It must be initialised outside the class definition
C++ allows the definition of our own types based on other existing data types. Use the schema:
In C++, the compiler is allowed to make one implicit conversion to resolve the parameters to a function. The compiler can use single parameter constructors to convert from one type to another in order to get the right type for a parameter. Prefixing the
explicit keyword to the constructor prevents the compiler from using that constructor for implicit conversions.