Month: August 2014

Arrays in C++

An array is a collection of scalar values of the same type, placed in consecutive memory locations and accessed via an identifier that devolves to a pointer to the base address combined with an offset value.

An array is a collection of data items of the same type, grouped under a single name and accessed by a number that indicates its location in the collection.

An array is a group of values accessed by an index number, which is placed in square brackets after the array’s name.  The index number counts from 0, not 1, because it indicates an offset from the base (or first) memory address of the array. Thus, item 1 is item 0, item 2 is item 1, and so on.

To declare a simple array, we declare the data type, followed by the array’s indentifier. It’s the same as a regular variable, with one addition: after the variable’s identifier, we place square brackets and a number. The number tells the compiler how many discrete items we want the array to be able to hold.

#include <iostream>


int main(void){

    //array of 10 ints
    int iaNums[10];

    //array of 10 doubles
    double daNums[10];

    //array of 20 chars
    double caChars[20];

    return 0;

}

Remember, an array is a homogeneous data structure, where all components are of the same data type.

Each item in an array is known as an element. An element is accessed by its position in the array. We specify the index value to access the element; note that array elements are counted from 0, not 1.

#include <iostream>

int main(void){

    int iaNums[5];

    iaNums[0] = 1138;
    iaNums[1] = 4004;
    iaNums[2] = 47;
    iaNums[3] = 1701;
    iaNums[4] = 1999;

    std::cout << "The first element is " << iaNums[0];
    std::cout << std::endl;

    std::cout << "The last element is " << iaNums[4];
    std::cout << std::endl;


    return 0;
}

As we have seen above, to access an array element, we write the array name, followed by an expression enclosed in square brackets. Although in the previous example we gave literal values, we can in fact place a variable or even a complex expression within the brackets, as long as the expression resolves to an integer. We can take advantage of this fact by using loops and variables to cycle through an array quickly.

#include <iostream>

using namespace std;

int main(void){

    int iaValues[5];

    int iIndex = 0;

    while(iIndex < 5){
        iaValues[iIndex] = iIndex * 3;
        iIndex++;
    }

    cout << "Third value: " << iaValues[2] << endl;
    cout << "First value: " << iaValues[0] << endl;

    

    return 0;
}

Note that C++ does not perform bounds checking, either at compile time or run time. Be careful!

It is possible to initialize an array at the time of its declaration. We specify a list of initial values for the array’s elements, separate them with commas, and enclose the list within curly braces.

#include <iostream>

using namespace std;

int main(void)
{
    double dArray[3] = {169.254, 802.11, 255.128};

    int i;

    for(i = 0; i < 3; i++){
        cout << dArray[i] << endl;
    }

    return 0;
}
        

By default, in C and C++ variables are passed by value. Arrays, however, are passed by reference. Note that when passing in an array, we must specify its upper bound either in a global variable or in a second argument.

#include <iostream>

#define LENGTH 5

using namespace std;

void printCharArray(char caArray[], int bounds);
void getGrades(char caGrades[]);

int main(void){

    char caGrades[7] = {'c', 'a', 'a', 'b', 'd', 'c', 'a'};
    char caGradesTwo[LENGTH];


    printCharArray(caGrades, 7);

    getGrades(caGradesTwo);

    printCharArray(caGradesTwo, LENGTH);


    return 0;
}


void printCharArray(char caArray[], int bounds){
    for(int i = 0; i < bounds; i++){
        cout << caArray[i] << endl;
    }
}

void getGrades(char caGrades[]){
    int i = 0;
    while(i < LENGTH){
        cout << "Enter the grade: ";
        cin >> caGrades[i];
        i++;
    }
}

In the even that we do not wish the called function to modify the contents of the array, we can use the reserved word const. We place the const reserved word before the parameter in the parameter list of the function.

 

 

 

 

 

 

Floating-Point Numbers in C++

Floating point numbers are numbers with fractional parts.

Floating point numbers can be written using standard decimal-point notation and E notation, where we specify the exponent and its mantissa.

#include <iostream>

using namespace std;

int main(void){

    double dutch = 1999E-2;
    double trouble = 19.99;

    cout << dutch << endl;
    cout << trouble << endl;

    return 0;
}

A floating point variable has both a whole number  part and a fractional part.  The internal representation of floating point numbers is much different from that of integers. To represent floating point numbers, we must be able to represent negative exponents. For instance, 42.47 = 4247 * 10 ^ -2. Likewise, .00411 = 411 * 10 ^ -5.  To use a negative exponent means to divide by a power of 10.

Significant digits are the meaningful digits in a number. The precision is the maximum number of significant digits. The C++ standard requires the float data type to have at least 32 bits, the double data type to have at least 48 bits, and the long double to be at least as large as the double. However, in most implementations float is 32 bits and double is 64 bits.

We can check these limits in the cfloat file.

#include <iostream>
#include <cfloat>

using namespace std;

int main(void){

    cout << "Num of bits in float mantissa: " << FLT_MANT_DIG << endl;
    cout << "Num of bits in double mantissa: " << DBL_MANT_DIG << endl;

    cout << endl;

    cout << "Minimum exponent value for float: " << FLT_MIN_10_EXP << endl;
    cout << "Minimum exponent value for double: " << DBL_MIN_10_EXP << endl;

    return 0;

}

When we declare a floating point variable, part of the memory is assumed to store the exponent, and mantissa is assumed to take up the remainder of the allocated space. The number of significant digits is fixed, whereas the decimal point is allowed to float right or left as necessary.

There is an ostream method called setf() that enables us to force output to stay in fixed-point notation

#include <iostream>

using namespace std;

int main(void){

    cout.setf(ios_base::fixed, ios_base::floatfield);

    float fValue = 26 / 7.0;
    double dValue = 26 / 7.0;

    cout << fValue << endl;
    cout << dValue << endl;

    cout << fValue << " * 1000 = " << fValue * 1000 << endl;
    cout << dValue << " * 1000 = " << dValue * 1000 << endl;

    return 0;

}

In general, it is better to use double than float. The double type is less prone to representational error, which occurs when the precision of the arithmetic operation is greater than the precision of the computational mechanism.

A real number that can be represented exactly as a floating point number is called a model number. A real number whose value can’t be represented exactly is instead approximated. The difference between the real number and its approximation is the absolute error; the absolute error divided by the real number is the relative error.

An interesting article on comparing floating point numbers can be found at http://floating-point-gui.de/errors/comparison/