DATA

Aims

To enable students to:

 ·	handle data types

 ·	scope variables and methods

 ·	validate data

 ·	use arrays

Handle data types

In course II (Elementary programming) the data types int, float and char were met. Many other data types also exists, but in this course only the type double will be introduced. Variables of type double are very similar to float, but take up twice the amount of room in memory and so can store double the range of numbers.

Some data types can also take modifiers, such as long, short, signed and unsigned, that change the type or range of data variables of that type contain. Modifiers are used as follows:

long int;
short int;
unsigned short int;
signed char;

The long modifier is used to extend the amount of data a variable referred to by the modifier stores. For example, on some systems an int is defined as two bytes, a long int as four bytes and a short int as two bytes. The signed modifier determines if the variable can store negative numbers, a signed short int can store values between -32,768 and 32,767 while an unsigned short int can store them between 0 and 65,535.

It is very common for developers to wish to assign variables of one type to those of another. Casting has been met as one way of achieving this, but this mechanism can result in the loss of data and is totally inappropriate in some circumstances (for example converting a string of characters into an equivalent number). C++ comes with several standard library routines for data conversion, for example atoi and atof will convert an ascii string to an int and an ascii string to a float. The following code shows the use of these functions:

#include <stdlib.h>

void main ()
{
      char szNumber1 = “100”;        // Store the string “100”
      int iNumber1;                  // iNumber1 is uninitialised

      iNumber1 = atoi (szNumber1);   // Sets iNumber1 to 100;

      iNumber1++;                    // iNumber1 is now 101
      
      char szNumber2 = “100.10”;     // Store the string “100.10”
      float fNumber2;                // fNumber2 is uninitialised

      fNumber2 = atof (szNumber2);   // fNumber2 is now 100.10

      fNumber2++;                    // fNumber2 becomes 101.10
}

The typedef keyword allows new data types to be declared. The new type may be a synonym for an existing one or entirely new. For example:

void main ()
{
      // Example of the typedef keyword

      typedef unsigned long ulong;  // Define ul as synonym for unsigned long
      ulong ul; 

      typedef struct mystructtag
      { 
            int i; 
            float f; 
            char c;
      } mystruct;                   // Define new data type

      mystruct ms; 
}

The typedef keyword allows developers to use pet words for data types. Its more serious use is to permit independence from a particular data type. If unsigned long variables are declared as ul throughout a program the data type can be changed from unsigned long to a larger data type in the future.

Scope variables and methods

All variables have what are termed visibility and lifetime. A variables visibility depends on where it is defined and under what storage class. For example external variables are visible throughout a program while static external variables may only be seen within the source file where they are defined.

Within classes the block of the class definition where the variable is declared controls its visibility. Public variables and functions may be seen outside of the class while private ones may not. In order to access public variables and functions outside of an object the access operators . and -> are used.

Objects created on the stack through standard variable declarations exist while the program is within the same code block as where the object was declared, as in:

void main ()
{
      int iValue = 3;

      if (iValue > 2)
      {
            Clocn position ();  // Object position of type Clocn declared

            iValue ++;
      }                      // Object position of type Clocn destroyed
}

The lifetime of an object depends on how it was created. Objects created on the heap using the new keyword live until they are destroyed with the delete keyword. When an object is created via new a pointer is provided to that object. This pointer must be provided to delete in order to destroy the object - if the pointer is lost the object can not be destroyed and the memory it occupies will be lost to the system.

Validate data

When reading data into a program it should always be validated to ensure only expected values are processed. By performing rigorous checks on data at the interface between the program and the rest of the world less checking is required internally.

Different reactions are needed to invalid data depending on its source. Information provided by a user could result in an error message being displayed and a request for the information to be entered again - for example:

void main ()
{
      char cInput;

      cin >> cInput;

      while (cInput != ‘y’)
      {
            cout << “Please enter a y”;
            cin >> cInput;
      }
}

Incorrect information in a file can not be easily asked for again - the program could be operating overnight with no humans present. In this case the program may terminate with an explanation of what it did not like about the file.

There are many standard library routines designed to help with validating data input, for example isupper (char) returns TRUE if the provided character is upper case, isprint (char) returns TRUE is the provided character is printable, etc.

The standard library routine strcmp is used to compare two strings (a string being an array of characters terminated by a NULL (numeric 0) character). It is defined as 

int strcmp( const char *string1, const char *string2 );

The routines compares string1 and string2 character by character. If both are identical a 0 is returned, if string1 is less than string2 a negative value is provided otherwise a positive one is.

Use arrays

Arrays have already been met in the City and Guilds C++ Programming II    course (7261-229).

An array is a series of contiguous memory locations storing data of the same type and accessed under the same variable name. To declare an array of ten elements of type int the following is entered:

int iArray [10];

Array elements are accessed by entering the subscript (numbering from zero) as a number between []:

int iValue;
int iArray [10];

…

iValue = iArray[0];  // Access the first element of the array
iValue = iArray[4];  // Access the fifth element of the array
iValue = iArray[9];  // Access the last element of the array

Arrays can also be initialised when declared as in:

int keyarray[4] = {102,36,75,999};

This format sets the integer array up so that the first element contains 102, the second 36, the third 75 and the last 999. This format is much easier than using array subscripts to set each element in turn, but unfortunately is only available when a variable is declared - it can not be used afterwards to modify an existing array.

It is so common to declare an array of type char to hold textual data    such as a name or address that C++ refers to them under a special name - strings. Strings are arrays of characters with the last element set to NULL (the numeric value 0). This permits routines to easily determine the length of a string - it is quite common for the string of characters to be smaller then the array used to store it.

Several string manipulation functions are provided by the standard libraries. 

To overwrite one string with another the strcpy function is used. The strcpy function is defined as

char *strcpy (char *strDestination, char *strSource);

The strcpy function will copy the string pointed to by strSource to the string pointed to by strDestination, returning a pointer to strDestination. The routine will copy all the characters from strSource to strDestination up to and including the NULL. For example

void main ()
{
      char strArray1 [20];
      char strArray2 [20];

      strcpy (strArray1, “Hello”);     // strArray1 contains “Hello\0”
      strcpy (strArray2, strArray1);   // strArray2 contains “Hello\0”
      strcpy (strArray2, “World”);     // strArray2 contains “World\0”
}

To concatenate strings the strcat function is used. The strcat function is defined as:

char *strcat (char *strDestination, char *strSource);

The strcat function will append the string pointed to by strSource to the end of the string pointed to by strDestination. For example:

void main ()
{
      char strArray1 [20];
      char strArray2 [20];

      strcpy (strArray1, “Hello ”);    // strArray1 contains “Hello \0”
      strcpy (strArray2, “World”);     // strArray2 contains “World\0”

      strcat (strArray1, strArray2);   // strArray1 contains “Hello World\0”
}