Showing posts with label Array. Show all posts
Showing posts with label Array. Show all posts

Sunday, September 6, 2009

Array vs vector

Vectors are intended to replace the C-style arrays, i.e. the static arrays:
  • Safe to pass as a parameter or assign to
  • Size increases when necessary means no memory management problem
  • Comparisons (==, < etc.) works "as it should"
vector has its own dangers, though:
  • No forced boundary limit checks in indexing
  • Easy to write code that may be inefficient in parameter passing
  • Passing arrays to libraries that use C arrays is difficult

Comparisons between C arrays and vector:

operationarrayvector
Creationint t[10]vector<int> t(10); or
vector<int> t; (empty)
Assignmentin a loopt1 = t2
Indexingt[i]t[i] or t.at(i)
Inserting to the endnot possiblet.push_back(item)
Combiningnot possiblet1.insert(t1.end(), t2.begin(), t2.end())
Sizeprogrammer must knowt.size()
Emptyingnot possiblet.clear()
Comparisonin a loopt1 == t2 (likewise <>
Insertion to the middlenot possiblet.insert(iterator, item)
Searchingin a loopfind(t.begin(), t.end(), item)
Exchange of valuesin a loopt1.swap(t2)


vector< type > var;
An empty vector
vector< type > var(vector< type >); Initialization with another vector
vector< type > var(int);A vector of the size int with elements of the type
vector< type > var(int, element);A vector with int elements initialized to element

Operations:
vector[int] // Indexing the vector at int.
vector1 = vector2 // Assignment
vector1 == vector2 // Comparison
vector1 != vector2vector1 < vector2vector1 <= vector2vector1 > vector2 vector1 >= vector2


Functions:
swap(vector1, vector2) // swaps the contents

Own functions:

type at( int )Indexing the vector at int
type front()The first element
type back()Last element
vector<type>::size_type size()number of elements
bool empty()true if vector is empty
void push_back(element)Element is added to the end of vector
void pop_back()Last element is removed, size gets smaller by one
void clear()Empty the vector completely
iterator being()An iterator to the beginning
iterator end()An iterator to the end


#include <algorithm>

Functions:

void sort( array, array+size );
void sort( vector.begin(), vector.end() );
// Sorting the vector or array into an ascending order
bool compare(const item&, const item&);
void sort( array, array+size, compare );
void sort( vector.begin(), vector.end(), compare );
// Sort can be given a comparison function as a third parameter
// Function returns true if the first parameter is smaller than the second.
void operations(const item&);
void for_each( array, array+size, operations );
void for_each( vector.begin(), vector.end(), operation );
// Calls the function operation for each element in the array or vector at a time.


Reference: cplusplus, velocityreviews, devx

Previous post

Next post


Vector

The C++ standard library offers the programmer plenty of generic data structures and algorithms that are ready for use. The programmer can concentrate on the essential and does not need to invent the wheel all over again. Just like string is dynamic and easier to use than static character strings, there is a dynamic data structure corresponding to static arrays. That is vector. vector is a part of the C++ standard library. The problems with arrays in C++:
  • They are static, i.e. the amount of elements cannot be changed without compiling the program again
  • An array cannot be copied into another away with the = operator
  • An array cannot be initialized with an another array
  • There is no way of knowing the current amount of actual elements without keeping constant score of the situation
vector makes all of the above possible and has a lot of other useful features. In practice, vector is generic, dynamic array.

In order to be able to use vector the library vector must be taken into use.

Any type of data can be put into a vector. All elements must be of the same type (just like with static arrays). vector is defined with <> notation:

vector< element_type > variable_name;

for example:

vector< int > numbers;
vector< string > names;

The vector is empty at initialization if no initial values are given:

vector< double > temperatures1( 5, 20.1 );
vector< double > temperatures2( 3 );
vector< double > temperatures3( temperatures2 );

now there are five elements in the vector temperatures1 with the value 20.1, all three elements in the vector temperatures2 have been initialized to 0.0 and the temperatures3 has the same contents as temperatures2.

Just like string, vector has its own functions.

vector <int> numbers(2,3);
//The elements in numbers are (3 3)
numbers.clear();
//numbers now empty
numbers.push_back(4);
numbers.push_back(10);
//Now the elements are (4 10)
numbers.push_back( numbers[1] );
//(4 10 10)
numbers.push_back( numbers.at( 0 ) );
//(4 10 10 4)
numbers.pop_back();
//(4 10 10)

// printing the contents
if( !numbers.empty() )
{
    unsigned int i;
    for( i = 0; i < numbers.size(); ++i )
    {
        cout << "numbers are: " << numbers[ i ] << " ";
    }
    cout << endl;
}

A vector can be assigned another vector of the same type with the = operator. Two vectors of the same type can be compared with ==, !=, <, >, <= and >= operators.

vector can be passed both as a value and a reference parameter like any ordinary variable:

vector<type> valueparam
vector<type>& referenceparam

In practice vector should always be passed as a reference parameter due to efficiency issues.

Reference: cplusplus, codesource, cppreference

Previous post

Next post


Saturday, August 29, 2009

Arrays as parameters

Even though call-by-value is the default parameter-passing mechanism in C++, arrays as parameters have some special features. Placing a pair of brackets ( [] ) after the name of a parameter indicates that the parameter is an array:

double arraySum( double array[ ], int array_size )
{
    double sum = 0.0;

    int i = 0;
    while( i < array_size )
    {
        sum = array[ i ] + sum;
    }
    return sum;
}

It is not necessary to specify the capacity of the array. There is no restriction on the capacity of the array passed to the function. It is necessary to use another parameter or a constant to pass the size of the array to the function.

Arrays are automatically passed by reference, i.e. specifying a parameter as an array makes it a reference parameter without the ampersand ( & ). If the function modifies the array, the corresponding argument will also be modified. This can be avoided by declaring the array as a constant reference parameter.

Let's take a larger example:

#include <cstdlib>
#include <iostream>

using namespace std;

const int MAX_NUMBER = 1000;
const int ERROR = -1;
const double END_NUMBER = -1.0;

int readNumbers( double numbers[ ] );
double calculateMean( const double numbers[ ], int how_many );

int main( void )
{
    double numbers[ MAX_NUMBERS ];
    int how_many_read = 0;

    how_many_read = readNumbers( numbers );

    if( how_many_read == ERROR )
    {
        return EXIT_FAILURE;
    }

    cout << "Mean value is: "
         << calculateMean( numbers, how_many_read )
         << endl;

    return EXIT_SUCCESS;
}

int readNumbers( double numbers[ ] )
{
    int how_many = 0;

    //we know that there is room for MAX_NUMBERS
    //amount of space in teh array
    while( how_many < MAX_NUMBERS )
    {
        cout << "Give "
             << how_many + 1
             << ". number: ";

        //The number is read from the input into
        //the array the change modifies the
        //coresponding argument
        cin >> numbers[ how_many ];

        if( numbers[ how_many ] == END_NUMBER )
        {
            return how_many;
        }
        ++how_many;
    }
    //if how_many got too large, and error has occured
    return ERROR;
}

double calculateMean( const double numbers[ ], int how_many )
{
    double sum = 0.0;
    int i = 0;

    if( how_many == 0 )
    {
        return sum;
    }

    //in this function the actual size of
    //the array doesn't matter. It is important
    //to know fo how many numbers the mean is
    //supposed to be calculated from
    while( i < how_many )
    {
        sum = sum + numbers[ i ];
        ++i;
    }
    return sum / how_many;
}


The other alternative woule have been:

int readNumbers( const double numbers[ ], int size )
{
    int how_many = 0;
    //now the size of the array is given as parameter
    while( how_many < size )
    {
        cout << "Give "
             << how_many + 1
             << ". number: ";
        //The number is read from the input
        //into the array the change modifies
        //the corresponding argument
        cin >> numbers[ how_many ];

        if( numbers[ how_many ] == END_NUMBER )
        {
            return how_many;
        }
        ++how_many;
    }
    //if how_many got too large, an error has occured
    return ERROR;
}

It would have been called in main:

how_many_read = readNumbers( numbers, MAX_NUMBERS );

The latter is recommended since the result can be used more widely.


Reference: cplusplus, macs, msdn


Previous post

Next post




Wednesday, August 26, 2009

Array

A variable of the type int or double can contain one value at a time. It would often be useful of the able to handle an aggregate of elements of the same type. An array is a structured datatype that:
  • has a specified size
  • consists of data elements of the same type
  • the elements are identified by their position in the array
In C++ array variables are declared:

type array_name[ capacity ];

The result is an array type variable named array_name in which data elements of the type type can be stored. The number of elements the array can contain is determined by capacity. type can be any defined type (predefined or programmer-defined). capacity needs to be a constant or a literal. For example, an integer array with nine elements:

int numbers[ 9 ];

An array can be seen as a row of numbered boxes, whose contents can be checked and changed. Every box fits one data element of the type type. In C++ arrays are indexed from zero through size-1.

int numbers[ 9 ] looks like this:

numbers:









 0  1  2  3  4  5  6  7  8 


the index of the last element is one smaller than the size of the array.

An element at index i can be accessed using [ ]:

numbers[8] = 2*numbers[0];

would give the last element the value of the first element times two. Any expression of the type integer can be used as an operand for the brackets.

For example,

const int SIZE = 10;

int maxValue( )
{
    int array[ SIZE ];
    int i = 0;
    int max = 0;
    while( i <>
    {
        cin >> array[ i ];
        if( array[ i ] > max )
        {
            max = array[ i ];
        }
        ++i;
    }
    return max;
}

No checking is done ot ensure that the indices stay within the range determined by the declaration of the array:

int index = 1000;
numbers[ index ] = 10; // logical error!

A compiler compiles the code above just fine. It is still incorrect because it refers to a non-existent element.

Like all variables, an array needs to be initialized with some sensible values before it can be used. An array can be initialized at declaration:


int numbers[ 9 ] = {1, 2, 3, 4, 5, 6, 7};

results in an array:

numbers:
 1  2  3  4  5  6  7  0  0 
 0 1 2 3 4 5 6 7 8


If there are less elements at initialization than the size of the array can contain, the rest of the elements are initialized to zero.

It is not necessary to tell the size of the array when initialized. It is automatically determined from the number of elements.

int numbers[ ] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

This is true only at initialization and cannot be used as a general method of handling array data. An array cannot be assigned another with =. Moreover, arrays cannot be compared with != and == operators. In array everything must be done one element at a time.

Arrays are static data structures. Their capacity cannot change during program execution. The capacity must always be fixed when the program is compiled:

int capacity = 0;
cin >> capacity;
int array[ capacity ]; // Error

results in a compilation error.


Reference: cplusplus, codesource, fredosaurus


Previous post

Next post