C++ - C++ Primer

This section will assume knowledge of Pascal and, instead of defining C as a programming language, it will focus on the differences between Pascal and C.

Structure

Blocks of code are denoted by curly brackets {} as opposed to the Pascal's begin/end. Each statement must end in a semi-colon. If a statement uses multiple lines in the source file, there must only be a semi-colon at the end of the last line.

A C program is a set of functions. Unlike Pascal, functions cannot be nested. Every function has to be defined in the global scope.
The compiler creates an program such that it will execute a function called main. This function defines the starting point of the program and is usually located at the very end, so that it can call all previously-defined functions. The main function corresponds to the main statement block in a Pascal program.

Example:
void main ()
{
}

Function Definition and Calls

Functions must be defined in the global scope - they cannot be nested. Every function definition adheres to the following syntax :

return-type function-name ( parameters ) { statements }

This corresponds to the following Pascal-style definition for a function:

function function-name ( parameters ) : return-type; begin statements end;

In the previous definition of the main function, the function return-type was void and there were no parameters or statements. Although the function has no parameters, the empty parameter list must still be included, unlike Pascal where it is normally omitted. The parameter list, when present is a comma separated list of formal parameters that conform to C syntax for data declarations.

A function header can be declared without a function body. This is used to declare that a function exists before defining it, so that subsequent functions can make use of it. The actual function can be defined much later in the program or even in a separate module.

Functions are called by simply using their function-names, together with a comma-separated list of actual parameters in brackets. Each parameter must be preceded by its data type - unlike in Pascal where a list of parameters can be associated with a single dat type. Parameters are only passed by value and C does not allow for variable parameters. There are two solutions to this problem and both will be discussed later.

The return-value indicates the data type of the value to be returned to the calling function. If the return type is void, then the function does not return a value, i.e. it is analagous to a procedure in Pascal. Procedure are all void functions - there is no separate syntax for them.
If a function with a non-null return value is called, and the return value has no meaning to the program, then it does not have to be assigned to any variable i.e. it can be treated as a void function.

Example:
void SampleFunction ( int a )
{
}

Functions can also have default values for parameters. In this case, if the function is called with fewer parameters than necessary, the default values are used for the rest. Default values can only be used for parameters at the end of the list.

Example:
void SampleFunction ( int a, int b=0, int c=1 )
{
}

Functions can be declared inline. When this is done, the code of the function is substituted at each point where it is should be called. This makes the machine code slightly faster as it can eliminate function calls for small functions.

Example:
inline void SampleFunction ( int a )
{
}

Functions can be overloaded in C++ i.e. there can exist two functions with the same name but different parameter sets. When an overloaded function is called, the compiler determines which clause to call by examining the parameter set.

Example:
void SampleFunction ( int a, int b )
{}
void SampleFunction ( int a )
{}

Data Types and Definitions

All names of functions and data types are case-sensitive. So Main would not be the same as main.

The basic data types are char, int and float. All other data types are derived from these.
Type modifiers can be used to change the range of data types. The most common modifiers are signed, unsigned and long.

char is a byte-sized number, which is signed by default. It has a range of -128 to 127. unsigned char is equivalent to a Pascal byte, with a range of 0 to 255. In C there is no difference between a byte and an ASCII character - both are numeric data types.

int is normally a 2-byte integer, equivalent to a Pascal integer. It has a range of -32768 to 32767. unsigned int is equivalent to a Pascal word, with a range of 0 to 65535. A larger number can be stored using a signed long int data structure, equivalent to a Pascal longint.

float defines floating-point numbers. For greater accuracy, double or long double can be used.

In all cases, variables are defined by the type name followed by a comma-separated list of the variables identifiers. Initial values can be assigned to variables by following the declaration with an "=" sign and the required value. Like all other statements, data declarations must be followed by a semi-colon.

In C++ data declarations are considered to be just like any other statement so can appear almost anywhere in a function. To enhance readability, it is advisable to keep them at the top of program blocks as far as possible. Global variables can be declared outside the context of any functions.

Example Type Declarations:
float             a,b,c;
int               aNumber, _dec=17, _oct=021, _hex=0x11;
unsigned long int Very_Big_Number =1000000L;
unsigned char     Key1='S', Key2=65;

Decimal constants are quoted verbatim. Octal constants must be preceded by a "0". Hexadecimal constants must be preceded by a "0x". Thus the values of the three integers in the above declaration are the same.
Long and short integers can be indicated by a trailing L or U respectively.
Characters can be indicated by either numbers of their corresponding ASCII characters.

Variables can be declared as constant by using the const keyword. This will ensure that the value of the variable cannot be changed. It can also be used in functions to ensure that the value of a pointer or reference parameter is not changed.

Example:
const int x = 1;

Advanced Data Types

Arrays are defined by a trailing pair of square brackets [], indicating the number elements in the array. All arrays begin at index 0 and end at number_of_elements-1. The syntax to use an array element is the same as in Pascal.
Multi-dimensional arrays are defined by a series of [].

Strings in C are simply arrays of characters. There is no separate syntax to define strings. Unlike Pascal, where the first character in the string indicated the length, C strings are null-terminated. Constant characters are indicated by single quotation marks while constant strings are indicated with double quotation marks.

Example:
int           anIntegerArray[10];
unsigned char Multi_Array[10][10];
char          aString[100];
char          aChar='a', String2="Hello";

Structures are the C implementation of records. Structure fields are accesses using the normal "." syntax.

Example:
struct name 
{
   char FirstName[100];
   char Surname[100];
}
struct name MyName;

Unions have a similar syntax to structures but they indicate situations where many variables occupy the same memory space. This is useful to typecast variables or to implement variant records in a database system.

Example:
union VariantRecord
{
   char Parent[100];
   char Guardian[100];
}

Variables can be declared static so that their values do not change across function calls.

Typecasting is supported by prefixing the variable with the new type within brackets.

User-defined types are defined using the keyword typedef followed by the type definition and then the new type name.

Enumerated types are allowed with the enum keyword but there is no subrange type.

Examples:
typedef unsigned int word
static word x;
float       y = (float)x;
enum numbers { zero, one, two };

Basic Operators

++ Increment
-- Decrement
! Logical NOT
sizeof Size in bytes
% Modulus (remainder)
== Equality (test)
!= Not equal
& Bitwise AND
| Bitwise OR
&& Logical AND
|| Logical OR
= Assignment
*=, +=, -=, /= Compound assignment
:: Scope Resolution

Directives

Compiler directives can be issued with special commands that are preceded by a "#".

The most common of these are #include and #define.
#include includes the code of an external file into the source at that point.
#define defines a macro.

Examples:
#define WIN31
#include <owl.h>

C has a wealth of standard functions available in external object modules. In order to use one of these functions, the header for the function must first be present in the source file. However, since this can be a tedious task, C provides a set of "include files" which each contain a set of function declarations. By including one of these "include files" with an include directive at the top of a program, that program then has access to all the functions whose headers appear in the "include file". This is the equivalent modular implementation to the Pascal unit.

Control Transfer Instructions

The for statement comprises three sections. The first specifies an initialization of variable/s, the second is the loop termination check and the last is the increment/decrement operation.

Example:
for ( a=0; a<10; a++ )
{
   printf ("Hello");
}

The while statement is identical to its Pascal counterpart, except that the brackets are compulsory.

Example:
while ( a!=10 )
   a++;

The do statement is analagous to Pascal's repeat.

Example:
do {
   a++;
} while ( a<=9 );

Within any of these iteration statements, there can appear either one of two additional constructs. The break statement exits immediately from the innermost loop, while the continue statement causes the next iteration of the innermost loop to occur.

Example:
for ( int a=0; a<10; a++ )
{
   if (Mark[a]<5)
      continue;
   if (Mark[a]>5)
      break;
   printf ("%u", Mark[a]);
}

The return statement is used to exit immediately from a function and, optionally, to return a value to the calling function.

Example:
return;
return aValue;

The if statement must have its condition enclosed in brackets and the first clause immediately follows the condition check i.e. there is no "then" keyword. Also, since the first clause is supposed to be a block of statements, there must be a terminating semi-colon, unlike in Pascal.

Example:
if ( a == 0 )
   printf ("Hello");
else
   print ("World");

Multiple condition checks can be accomplished with a switch statement. The variable whose value is being checked is placed in brackets after the switch keyword. Each clause within brackets thereafter is preceded by the keyword case followed by a possible value for the discriminating variable and a colon. The keyword default can indicate a default set of statements and usually appears at the end. Unlike Pascal, each set of statements is not a block, so the statements from a preceding case can continue into the next one. To prevent this, a break instruction must be the last instruction for each case.

Example:
switch (a)
{
   case 0 : printf ("Hello");
            break;
   case 1 : printf ("World");
            break;
   default : printf ("YAY");
}