Data Structures

Document Sample
Data Structures Powered By Docstoc
					Data Structures
Summary
Creating structure

Accessing structure elements/members

Nested structures

Structures and arrays

Structures and structures

Structures and functions

Structures and pointers

Passing parameters

User defined data types
                      Data Structures
• A data structure is a group of data elements grouped together
  under one name. These data elements, known as members, can
  have different types and different lengths.

  where structure_name is a name for the structure type,
  object_name can be a set of valid identifiers for objects that have
  the type of this structure. Within braces { } there is a list with the
  data members, each one is specified with a type and a valid
  identifier as its name.

     struct structure_name {
     member_type1 member_name1;
     member_type2 member_name2;
     member_type3 member_name3;
     .
     .
     } object_names;
A data structure creates a new type:

Once a data structure is declared, a new type with the identifier
specified as structure_name is created and can be used in the rest
of the program as if it was any other type.

Example:


     struct product {            We have first declared a structure
      int weight;                type called product with two
      float price;               members: weight and price, each of a
     };                          different fundamental type. We have
                                 then used this name of the structure
     product apple;              type (product) to declare three objects
     product banana, melon;      of that type: apple, banana and
                                 melon as we would have done with
                                 any fundamental data type.
Once declared, product has become a new valid type name like the
fundamental ones int, char or short and from that point on we are able to
declare objects (variables) of this compound new type, like we have done
with apple, banana and melon.

Right at the end of the struct declaration, and before the ending semicolon,
we can use the optional field object_name to directly declare objects of the
structure type. For example, we can also declare the structure objects apple,
banana and melon at the moment we define the data structure type this
way:


    struct product {                      struct product {
      int weight;                          int weight;
      float price;                         float price;
    } apple, banana, melon;               };

                                          product apple;
                                          product banana, melon;
                     struct product {
                      int weight;
                      float price;
                     };

                     product apple;
                     product banana, melon;

• It is important to clearly differentiate between what is the structure
  type name, and what is an object (variable) that has the structure
  type.
• We can instantiate many objects (i.e. variables, like apple, banana
  and melon) from a single structure type (product).
• Once we have declared the objects of a determined structure type
  (ex. apple, banana and melon) we can operate directly with their
  members.
• To do that we use a dot (.) inserted between the object name and
  the member name. For example, we could operate with any of these
  elements as if they were standard variables of their respective types:
                                    struct product {
Example:                              int weight;
                                      float price;
                                    } apple, banana, melon;
apple.weight apple.price
banana.weight banana.price
melon.weight melon.price

Each one of these has the data type corresponding to the
member they refer to:

Example:

apple.weight, banana.weight and melon.weight are of type
int,
while apple.price, banana.price and melon.price are of
type float.
                  // example about structures
how a structure                                              Enter title: Alien
                  #include <iostream>
type can be       #include <string>                          Enter year: 1979
                  #include <sstream>
used in the       using namespace std;
same way as                                                  My favorite movie is:
fundamental       struct movies_t {                           2001 A Space Odyssey (1968)
types               string title;                            And yours is:
                    int year;                                 Alien (1979)
                  } mine, yours;

                  void printmovie (movies_t movie);
                  int main ()
                  {
                    string mystr;
                    mine.title = "2001 A Space Odyssey";
                    mine.year = 1968;

                   cout << "Enter title: ";
                   getline (cin,yours.title);
                   cout << "Enter year: "; getline (cin,mystr); stringstream(mystr) >> yours.year;

                   cout << "My favorite movie is:\n ";
                   printmovie (mine); cout << "And yours is:\n ";
                   printmovie (yours);
                   return 0;}

                  void printmovie (movies_t movie)
                  {
                  cout << movie.title; cout << " (" << movie.year << ")\n";
                  }
The example shows how we can use the members of an object
as regular variables.

For example, the member yours.year is a valid variable of type
int, and mine.title is a valid variable of type string.

The objects mine and yours can also be treated as valid
variables of type movies_t,

for example we have passed them to the function printmovie as
we would have done with regular variables.

Therefore, one of the most important advantages of data
structures is that we can either refer to their members
individually or to the entire structure as a block with only one
identifier.
Arrays:

An array is a series of elements of the same type placed in contiguous
memory locations that can be individually referenced by adding an index to
a unique identifier.

That means that, for example, we can store 5 values of type int in an array
without having to declare 5 different variables, each one with a different
identifier. Instead of that, using an array we can store 5 different values of
the same type, int for example, with a unique identifier.

For example, an array to contain 5 integer values of type int called billy
could be represented like this:

where each blank panel represents an element of the array, that in this case
are integer values of type int.

These elements are numbered from 0 to 4 since in arrays the first index is
always 0, independently of its length.
Like a regular variable, an array must be declared before it is used.


type name [elements];

where type is a valid type (like int, float...), name is a valid identifier and the
elements field (which is always enclosed in square brackets []), specifies how
many of these elements the array has to contain.

Therefore, in order to declare an array called billy as the one shown in the
above diagram it is as simple as:

int billy [5];

 Initializing arrays:

 int billy [5] = { 16, 2, 77, 40, 12071 };
Accessing arrays:

name[index]




Multi dimensional array:

Multidimensional arrays can be described as "arrays of arrays".
For example, a bi dimensional array can be imagined as a bi dimensional table
made of elements, all of them of a same uniform data type.

int jimmy [3][5];

jimmy[1][3]
Structures and Arrays:

Array of structures:

Arrays: Collection of elements of same type
Structures: Collection of dissimilar type elements

Example
struct addr
{
           int houseno;
           char area [20];
           char city [20];
           char state [20];
}

Struct emp
{
          int empno:
          char name[20];
          addr address;
          float salary;
} employee;

emp sales_man[10];      // creates array of structures of emp type
Arrays within structures:

A complex structure may itself be a structure of an array. When a structure
element happens to be an array, it is treated in the same way as arrays are
treated.

Struct student
{
          int rollno;
          char name[20];
          float marks [5];   //array marks is member element of structure student

}student learner;
Passing structures to functions:

Global structures available to all the functions within program but if we have
structure local to a function and need to pass its values to another function, it can
be achived by two ways

1. By passing individual structure elements and
2. By passing the entire structure

Both these ways can be achieved by call by value as well as call by reference
method of passing variables.

struct date {
       short day;
       short month;
       short year;
} Bdate;

Individual elements of this structure can be passed as
       func1(Bdate.day, Bdate.month, Bdate.year);
Passing entire structure to functions:

Call by value/Call by reference:

Passing by value is used when the original values are not to be changed
and passing by reference is useful when original values are to be changed.
Returning Structures from functions:

Functions can return structures also. The return type of the function is
same as that of the structure returned.
User defined data types:

Can define explicitly new data type names by using keyword
typedef. Using typedef does not actually create a new data
calss, rather it defines a new name for an existing type.

typedef float amount;

New name for the type float has been created through typedef
This statement tells the compiler to recognize amount as an
alternative name for float.

Now we can create float variable using amount
amount loan, saving, salary;
#define preprocessor directive:

Preprocessor commands are called DIRECTIVES and begin with
a proud /hash symbol.

A semi column is not required

Evaluated by preprocessor in preprocessing phase before the source
code is compiled.

Example

#define PI 3.14159
                   // array of structures                     Enter title: Blade Runner
Data structures
                   #include <iostream>                        Enter year: 1982
are a feature      #include <string>                          Enter title: Matrix
that can be        #include <sstream>                         Enter year: 1999
used to            using namespace std;                       Enter title: Taxi Driver
                                                              Enter year: 1976
represent
                   #define N_MOVIES 3
databases,                                                    You have entered these movies:
especially if we   struct movies_t {                          Blade Runner (1982)
                    string title;                             Matrix (1999)
consider the                                                  Taxi Driver (1976)
                    int year;
possibility of     } films [N_MOVIES];
building arrays
of them:           void printmovie (movies_t movie);
                   int main ()
                   {
                     string mystr; int n;
                     for (n=0; n<N_MOVIES; n++)
                     {
                      cout << "Enter title: ";
                      getline (cin,films[n].title);
                      cout << "Enter year: ";
                      getline (cin,mystr);
                      Stringstream(mystr) >> films[n].year;
                     }
                     cout << "\nYou have entered these movies:\n";
                     for (n=0; n<N_MOVIES; n++) printmovie (films[n]);
                     return 0;
                   }
                   void printmovie (movies_t movie) {
                     cout << movie.title; cout << " (" << movie.year << ")\n";
                    }
Array of structures:

#include <iostream.h>
#include <stdlib.h>
#define Length 5
struct Employee {
  char title [50];
  int year;
} employee [Length];
void printemployee (Employee employee);
int main ()
{
  char buffer [50];
  for (int n=0; n<Length; n++)
  {
    cout << "Enter title: ";
    cin.getline (employee[n].title,50);
    cout << "Enter year: ";
    cin.getline (buffer,50);
    employee[n].year = atoi (buffer);
  }
  cout << "\nYou have entered these employees:
\n";
  for (int n=0; n<Length; n++)
    printemployee (employee[n]);
  return 0;
}
void printemployee (Employee employee)           Enter title: Title
{                                                Enter year: 123
  cout << employee.title;                        Enter title: Title 2
  cout << " (" << employee.year << ")\n";        Enter year: as
}
                                                 Enter title: TitEnter year: ^CTerminate batch job
                                                 (Y/N)? n
Pointers:
The declaration of pointers:

type * name;

where type is the data type of the value that the pointer is intended to point to.
This type is not the type of the pointer itself! but the type of the data the pointer
points to.

For example:

int * number;
char * character;
float * greatnumber;
Reference operator (&):

The address that locates a variable within memory is what we call a reference
to that variable.

This reference to a variable can be obtained by preceding the identifier of a
variable with an ampersand sign (&), known as reference operator,
and which can be literally translated as "address of".

For example:

ted = &andy;

This would assign to ted the address of variable andy, since when preceding
the name of the variable andy with the reference operator (&) we are no longer
talking about the content of the variable itself, but about its reference (i.e., its
address in memory).
For now on we are going to assume that andy is placed during runtime in the
memory address 1776. This number (1776) is just and arbitrary assumption we
are inventing right now in order to help clarify some concepts in this tutorial, but in
reality, we cannot know before runtime the real value the address of a variable
will have in memory.

Consider the following code fragment:

andy = 25;
fred = andy;
ted = &andy;

The values contained in each variable after the execution of this, are shown in the
following diagram:
First, we have assigned the value 25 to andy (a variable whose address in
memory we have assumed to be 1776).

The second statement copied to fred the content of variable andy (which is 25).
This is a standard assignment operation.

Finally, the third statement copies to ted not the value contained in andy but a
reference to it (i.e., its address, which we have assumed to be 1776). The reason
is that in this third assignment operation we have preceded the identifier andy
with the reference operator (&), so we were no longer referring to the value of
andy but to its reference (its address in memory).

The variable that stores the reference to another variable (like ted in the previous
example) is what we call a pointer.
Dereference operator (*):
A variable which stores a reference to another variable is called a pointer.

Pointers are said to "point to" the variable whose reference they store.
Using a pointer we can directly access the value stored in the variable
which it points to.

To do this, we simply have to precede the pointer's identifier with an asterisk (*),
which acts as dereference operator and that can be literally translated to
"value pointed by". Therefore, following with the values of the previous example,
if we write:

beth = *ted;

(that we could read as: "beth equal to value pointed by ted")
beth would take the value 25, since ted is 1776, and the value pointed by 1776 is 25.
You must clearly differentiate that the expression ted refers to the value 1776, while
*ted (with an asterisk * preceding the identifier) refers to the value stored at address
1776, which in this case is 25.

Notice the difference of including or not including the dereference operator.
beth = ted; // beth equal to ted ( 1776 )
beth = *ted; // beth equal to value pointed by ted ( 25 )

Notice the difference between the reference and dereference operators:

& is the reference operator and can be read as "address of"
•is the dereference operator and can be read as "value pointed by"

Thus, they have complementary (or opposite) meanings. A variable referenced with
& can be dereferenced with *.
Earlier we performed the following two assignment operations:
andy = 25;
ted = &andy;

Right after these two statements, all of the following expressions would give true as result:

andy == 25
&andy == 1776
ted == 1776
*ted == 25

The first expression is quite clear considering that the assignment operation performed on
andy was andy=25.

The second one uses the reference operator (&), which returns the address of variable
andy, which we assumed it to have a value of 1776.

The third one is somewhat obvious since the second expression was true and the
assignment operation performed on ted was ted=&andy.

The fourth expression uses the dereference operator (*) that, as we have just seen, can
be read as "value pointed by", and the value pointed by ted is indeed 25.

So, after all that, you may also infer that for as long as the address pointed by ted remains
unchanged the following expression will also be true: *ted == andy
Pointers to structures:
Like any other type, structures can be pointed by its own type of pointers


struct movies_t {
  string title;
  int year;
};
movies_t amovie;
movies_t * pmovie;

Here amovie is an object of structure type movies_t, and pmovie is a
pointer to point to objects of structure type movies_t. So, the following
code would also be valid

pmovie = &amovie;

The value of the pointer pmovie would be assigned to a reference to
the object amovie (its memory address).
// pointers to structures
                                             Enter title: Invasion of the body
#include <iostream>
#include <string>                            snatchers
#include <sstream>                           Enter year: 1978
using namespace std;
                                             You have entered:
struct movies_t {                            Invasion of the body snatchers (1978)
    string title;
    int year;
};
                                             The -> operator is used exclusively
                                             with pointers to objects with
int main ()                                  members.
{
     string mystr;                           This operator serves to access a
                                             member of an object to which we
    movies_t amovie;                         have a reference.
    movies_t * pmovie;
    pmovie = &amovie;                        pmovie->title is equalent to (*pmovie).title

    cout << "Enter title: ";                 Both expressions pmovie->title and
    getline (cin, pmovie->title);            (*pmovie).title are valid and both mean that
    cout << "Enter year: ";                  we are evaluating the member title of the data
    getline (cin, mystr);                    structure pointed by a pointer called pmovie. It
    (stringstream) mystr >> pmovie->year;    must be clearly differentiated from:
                                             *pmovie.title which is equavalent to (*pmovie).title
    cout << "\nYou have entered:\n";
    cout << pmovie->title;
    cout << " (" << pmovie->year << ")\n";

    return 0;
}
•   Summary of possible combinations of pointers and structure members:

      Expression                What is evaluated                 Equivalent
     a.b             Member b of object a
     a->b            Member b of object pointed by a             (*a).b
     *a.b            Value pointed by member b of object a       *(a.b)
Nesting structures:

Structures can also be nested so that a valid element of a structure can also be
in its turn another structure.

struct movies_t {                            After the declaration we could use
  string title;                              any of the following expressions:
  int year;
};                                          charlie.name
                                            maria.favorite_movie.title
struct friends_t {                          charlie.favorite_movie.year
  string name;                              pfriends->favorite_movie.year
  string email;
  movies_t favorite_movie;                   (btw, the last two expressions refer
} charlie, maria;                            to the same member).

 friends_t * pfriends = &charlie;

				
DOCUMENT INFO