Resources

Variables, constants and enumerations within C++

Aims

To enable students to:

  1. declare and use variables

  2. handle constants

  3. declare enumerators

  4. manipulate arrays

  5. carry out arithmetic operations

  6. understand operator precedence

Declare variables of an appropriate data type

C++ has many in built data types, but in this course we are only really concerned with integers (int), characters (char) and floats (float).

As expected integers and floats can be manipulated using the standard mathematical operators (+, -, /). But characters can also be manipulated in the same way. Remember, within the program C++ treats characters as integers. The letter stored, for example 'A', is not represented in memory as 'A', but rather the value 65. Consequently this variable can be manipulated using standard mathematical operators, e.g. adding one to the variable will cause its value to become 66 ('B').

When manipulating values that can not have fractional portions, such as calendar dates, an integer is used. The following code sets ivalue1 to 17 and ivalue2 to 34:

int iValue1;

int iValue2;

iValue1 = 17;

iValue2 = iValue1 * 2;

Values that can have fractional portions, such as a persons height, are stored in floats. The following code will leave fValue set to 8.5, note when assigning a constant value (such as 17.0) to a float the number should have a suffix of l otherwise the compiler will treat it as a double type and generate a warning:

float fValue;

fValue = 17.0f;

fValue = fValue / 2;

Characters are used to store individual letters, such as 'A', 'F', etc. The following code leaves cValue set to 'A' (integer value 65).

char cValue;

cValue = 'Z';

cValue = cValue - 'Y' + 64;

C++ presents very few restrictions on assigning variables of one type to another. During compilation if a variable of type float is assigned to one of int a warning will be produced, but object code will be generated. When the program is eventually run the assignment will result in loss of precision, for example if a float of 22.55 was assigned to an int the int would only contain 22 (the .55 is lost). If you are sure the assignment is correct and the loss of precision is acceptable the warning may be suppressed through casting - the data type of the destination variable is placed in brackets before the source variable, for example:

float fValue = 17.05f;

int iValue;

iValue = (int) fValue;

Where possible avoid assigning variables of one type to another - it is potentially very dangerous. Only assign values of variables of **compatible **types.

Handle constants

Constants can be defined in two ways, via the preprocessor or through source code statements. By convention they are normally defined at the top of a source file just after the library header files have been included, but the C++ compiler does not enforce this. To declare a constant through the preprocessor the #define directive is used, for example to the following represents the number of days in a year:

#define DAYS_IN_YEAR 365

Alternatively the same effect can be achieved via the following

const int DAYS_IN_YEAR = 365;

The latter is generally preferred in C++ circles, but both are equally acceptable.

Declare enumerators

So far we have met the standard data types char, int and float. C++ provides many more, but even these may not meet the requirements of the programmer.

As an example, a diary application needs to store the current day of the week - it is possible to use and integer with 0 representing Sunday and 6 Saturday but this is unfriendly. It would be very useful if a type existed that could take the values sun, mon, tue, etc. through to sat. This would permit the developer to refer to a given day as tue instead of 2 - far friendlier.

In fact it is possible for developers to define their own data types and achieve exactly this flexibility using enumeration types. In the days of the week example an enumeration type is declared as follows:

enum day {sun, mon, tue, wed, thu, fri, sat};

C++ stores enumeration types as integers, the first enumerator (in the above example sun) has a value of 0 with each successive enumerator being one larger than the previous (i.e. mon is 1, tue is 2, etc.)

// Example of the enum keyword
enum day // Declare enum type day
{
sun, // sunday = 0 by default

mon, // monday = 1

tue, // tuesday = 2

wed, // etc.

thu,

fri,

sat
};

day today; // Variable today has type Days

int tue; // Error, redefinition of tue

day yesterday; // Variable yesterday has type Days

yesterday = mon;

int i = tue; // Legal; i = 2

As C++ treats enumerated types as integers sending a variable of this type to cout results in a number being displayed, for example

cout << yesterday

results in an output of 1.

Manipulate arrays

In the real world problems are rarely made up from single values, temperatures over several days need to be averaged out, people have names longer than one character, football results need a pair of numbers, etc.

Single instances of floats, chars and integers can not meet these requirements. Instead several values need to be treated as a whole - this can be achieved through arrays.

Any data type can be used in an array, but perhaps the most common use of arrays is to store a series of characters (a string). For example to hold a weeks worth of temperatures the following declaration is made:

float fTemperatures [7];

The above statement allocates seven contiguous floats in memory. Access to an individual element of the array (a subscript), say the third, is achieved using the following notation:

cout << fTemperatures [2];

Likewise, the following sets the fifth element to the value 22.45:

fTemperatures [4] = 22.45f;

Note, the index (number in []), of an array always starts at 0. In the fTemperatures array we have an index running from 0 through 6.

It is not possible to assign one array to another, for example assuming we have two char arrays (strings) the following is not possible:

szName1 = szName2;

Obviously this is somewhat frustrating. Many memory manipulation routines are available in the system libraries, to copy one string to another the strcpy function is used. strcpy is defined by the header file string.h

To copy one array to another use the following code fragment:

strcpy (szDestination, szSource);

It is equally possible to use string constants, such as

strcpy (szDestination, "Hello, world");

Carry out arithmetic operations

C++ provides five main arithmetic operators to manipulate numeric values * (multiplication), / (division), % (modulus), + (addition) and - (subtraction). Most should be familiar, only the division and modulus operators need some explanation.

As integers can only hold whole numbers, division operations can produce unexpected results. For example the following code set i3 to 3 - the fractional part is lost.

int i1 = 10;

int i2 = 3;

int i3 = i1 / i2;

In order to discover the fractional portion of the division operation the modulus operator is used, as in:

int i4 = i1 % i2;

which gives i4 the value of 1.

When dealing with floats these operators behave differently, for example the following code sets f3 to 3.33333:

float f1 = 10.0f;

float f2 = 3.0f;

float f3 = f1 / f2;

The modulus operator can not be applied to variables of type float.

C++ is keen on minimising effort on behalf of programmers. Keywords tend to be short (and cryptic!). In line with this theory shorthand forms of arithmetic operators are available, as in:

int i1 = 5;

int i2 = 10;

i1 = i1 + i2; // Add i1 to i2

i1 += i2; // Add i1 to i2

i2 = i2 - i1; // Subtract i1 from i2

i2 -= i1; // Subtract i1 from i2

i1 = i1 + 1; // Add 1 to i1

++i1; // Add 1 to i1

i2 = i2 - 1; // Subtract 1 from i2

--i2; // Subtract 1 from i2

Note, the ++ and -- operators can be placed in front or behind the variable to be incremented. The position of the operator has a subtle effect on the order of execution, when in front (++i1) the value of i1 is first incremented and then used, when after (i1++) the value of i1 is used and then incremented. In the example above the positioning of the increment or decrement operator make no difference, but in some cases (such as loop control) it is critical.

Understand operator precedence

C++ arithmetic operators follow these rules of precedence:

Operator   Precedence
( ) Highest, quantities in brackets are evaluated first, nested brackets are evaluated innermost first.
++ -- Second highest
* / % Third highest
+ - Lowest

 

For example the following will assign the value of 7 to iValue:

iValue = 2 * 3 + (4 - 2) / 2;

Downloads