# Pointers to Structures

Λογισμικό & κατασκευή λογ/κού

14 Δεκ 2013 (πριν από 4 χρόνια και 5 μήνες)

86 εμφανίσεις

Data
Types and
Structures

C++ provides large collection of data types and structures

Fundamental data types, arrays, structs, and unions are provided both
in C and C++. But, other structured data types are available only in
C++.

ARRAYS

Are c
ollect
ion of data elements

Such that a
ll of

elements are

same type

Each
element is
accessed by specifying position

Static array

Compiler determines how memory allocated

Dynamic array

Allocation takes place at run time

One
-
dimensional Arrays

Syntax:

ElementTy
pe

arrayName [CAPACITY];

ElementType

a
rrayName [CAPACITY] =
{ initializer_list };

Example:

int b [10];

int a[]={1,2,10,30, 5};

Elements accessed by

name and [ ] operation

For example, cout << b[5];

yi
elds 55

Elements of an array may be of any type

Including characters

Example:

char name [NAME_CAPACITY] =
"John Doe";

Extra locations are
filled with null

Note
: NOT Always

We have s
aid elements accessed
by name and [ ] numList[5]

Consider the [ ] to be an operator

The subscript operator

translation

Name of the array is a pointer
constant

Note use of arrays as parameters

Must specify number of elem
ents of array being used

Accessing Array for Output

void display(int theArray[], int numValues)

/*
-
----
-------------------
---------------------------------

Display values in an array of integers.

Precondition: 0 <= numValues < capacity of theArray.

Postcondition: The first numValues integers stored in
theArray have been output to cout.

-
-----------------------------------
---------------------
*/

{

for (int i = 0; i < numValues; i++)

cout « theArray[
i] « “ “ ;

cout « endl;

}

Array Input Function

#include <cassert>

void read(IntArray theArray, int capacity, int numValues)

/*
----------------------------------
----------------------------------

Input values into an array of integers from the keyboard.

Preconditions: 0 <= numValues < capacity, which is the capacity of
theArray.

Postcondition: numValues integers entered from the keyboard

have been stored in
the first NumValues positions of theArray

---------------------------------------------------------------------
/*

{

assert (numValues >= 0 && numValues <= capacity);

for (int i = 0; i < nurnValues; i++)

cin » theArray[i] ;

}

Out of Range Errors

Most C++ compilers do not by default check indices for out of range

Results of out of range array access

Program can exceed allowed memory area

Program can give puzzling results

*
-------------------------------
----------------------
--------

Demonstration of what can happen when array indices get out of bounds.

Input: Three arrays of integers

Output: The three arrays before and after modification using

out
-
of
-
range indices.

-------------------------------------------
-----------------
*/

#include <iostream>

using namespace std;

const int CAPACITY = 4;

typedef int IntArray[CAPACITY];

void read(IntArray theArray, int capacity, int numValues);

void display(IntArray theArray, int numValues);

int main(){

IntArray a, b,

c;

cout << "Enter " << CAPACITY << " integer values for:
\
n";

cout << "Array a: ";

cout << "Array b: ";

cout << "Array b: ";

cout << "
\
n
----
--

Part I of the demonstration
-----
\
n
\
n"

"The arrays are:
\
n";

cout << "a: ";

display(a, CAPACITY);

cout << "b: ";

display(b, CAPACITY);

cout << "c: ";

display(c, CAPACITY);

//
---

Now change array elements in b, but using

//
---

some out
-
of
-
range indices.

int below =
-
3,

above = 6;

b[below] =
-
999;

b[above] = 999;

cout << "
\
n
------

Part II of the demonstration
-----
\
n
\
n"

"The arrays after out
-
of
-
range errors are:
\
n";

cout << "a: ";

displ
ay(a, CAPACITY);

cout << "b: ";

display(b, CAPACITY);

cout << "c: ";

display(c, CAPACITY);

cout << endl;

return 0
;

}

Problems with C
-
style Arrays

Capacity cannot change.

An array is not an object

(in the OOP sense)

Virtu
ally no predefined
operations
for

non
-
char arrays.

The Deeper Problem:

C
-
style arrays aren't self
-
contained

Data, functions, and size not encaps
ulated

Multidimensional Arrays

Consider a table of test scores for several different students

Two
-
dimensional array

Syntax:

ElementType arrayName [numRows][numCols]
;

Three Dimensional

Consider multiple pages of the student grade book

const int NUM_ROWS =

10, NUM_COLS = 5,

NU
M_RANKS = 10;

typedef double
ThreeDimArray[NUM_ROWS][NUM_COLS][NUM_RANKS]
;

Memory Allocation

Passing arrays in functions

One dimensional arrays;

void display( int table[], int N
);

Example: Is the following valid?

void display( int table[][], int rows, int cols );

You must fill the constant number of the column:

void display( int table[][COLS], int rows, int cols );

3
-
D?

void display( int table[][COLS]
[RANKS]
, int
rows, int cols
, ranks

);

Dynamic Arrays

Recall:

What is a pointer variable? How to use it?

After declaring a pointer variable, assign an

int i = 2;

int * p;

p = & i;

//
Note:
i
has been declared before

Elements stored
in
row
-
wise
order

Also called
column major
order

location [0][4] is
followed in memory
by loca
tion [1][0]

Static method (
i is

in a static memory:

assigned in compile time !)

By the way, program cannot assign address to

the pointer directly such as

p = 0X13eff860

Dynamic Memory Allocation

The
new
operation

Example

int * intPtr;

intPtr = new int;

New function returns

a memory address that can store “int” type data
operator and
release it with delete operator.

Usually, dynamic allocation is
done
with assignment or initiation:

type *p;

p = new type;

//or

type* p = new type;

Examples:

int* ip;

ip = new int;

*ip = 100;

// constant integer value

float* np = new float;

cin >> *np;

char* cp = new char;

*cp = 'X';

// char
acter

Operator Delete

When done using the memory, return it to

free store by using delete:

Example:

delete p;

Result of delete :

-

return the storage (deallocation)

-

p still exists, but the address stored in p is

meaningless,

-

Hence, set it to

NULL:

p
= NULL;

In sum, if we

don’t

need pointers to point to a

data

anymore, we should

delete ip;

delete np;

delete cp;

Dynamic Arrays

Recall: static array is fixed size at

compile time

Space wasted by unused cells

Program cannot adjust if size s
et too

small

Dynamic (run time) allocation provided

Acquire memory as needed

Release memory when no longer

needed

The new operator

Syntax for arrays

new Type [capacity]

This command issues a run
-
time request for a block of memory

of

S
i
ze

=

type *
capacity

Asks for enough memory for the specified number of elements of the stated type

Example

int *arrayPtr;

//
get for a 4 byte storage

arrayPtr = new int[6];

/
ed

by
new function is copied

//
into memory location pointed by arrayPtr

Failures of
new

When new execute
s

There is a

r
equest of

memory from heap (free dynamic
memory part)

Operating system a
llocates that

block to executing program

It is p
ossible to use up available heap memory

If
there is
not enough memory for request
, what happens?

new throws an exception …

Solution: U
se
try

and
catch

mechanism to take appropriate action,

Example:

//
--

Demonstration #1 of new failure
--

exception

#
include <iostream>

using namespace std;

int main()

{

const int NUM_ARRAYS = 10;

cout << "How large should the arrays of doubles be? ";

int capacity;

cin >> capacity;

double * arrayPtr[NUM_ARRAYS];

int i;

for (i = 0; i < NUM_ARRAYS; i++)

{

arrayPtr[i] = new double [capacity];

cout << "Allocated " << capacity

<< " doubles for i = " << i << endl;

}

// If a failure happened we are not aware, since program will
not

//
crush, if it cannot allocate heap memory.

cout << "All " << NUM_ARRAYS << " arrays of "

<< capacity << " doubles were allocated successfully." <<
endl;

}

Example:

//
--

Demonstration #2 of new failure
--

Use try
-
catch
mechanixm

//
--

ion.

#include <iostream>

#include <new>

using namespace std;

int main()

{

const int NUM_ARRAYS = 10;

cout << "How large should the arrays of doubles be? ";

int capacity;

cin >> capacity;

double * arrayPtr[NUM_ARRAYS];

int i;

try

{

for (i = 0; i < NUM_ARRAYS; i++)

{

arrayPtr[i] = new double [capacity];

cout << "Allocated " << capacity

<< " doubles for i = " << i << endl;

}

}

catch

{

cout << "
\
nException: " << ex.what()

<< "
--

for i = " << i << endl;

exit(1);

}

cout << "All " << NUM_ARRAYS << " arrays of "

<< capacity << " doubles were allocated
successfully." << endl;

}

Pointer Arithmetic

Possible to alter pointer contents

The pointer is a
variable

It is not a pointer constant like an array name

Example

Given:

Then
, after

arrayPtr
++;

Poi
nter to an array can do + and

an integer

operations such as

p = p + i;
and

p = p
-
i;

where
p
is a pointer to an array and
i
is an integer.

For example (draw the diagrams for understanding!),

int a[20]

int * p
;

p
= a;
// we
can do

++p;

// p points to a[1]

p+=2;

p = & a[10]; // p points to a[10]

p = p

5;

// now, p points to a[5]

Assignment
: What happens if
we

do
++a; a += 2
?

Write a program and find out!

Example:

The
delete
Operation Again

Counterpart to the
new
operation

Requests memory be returned to the heap,

can then be reused by later
allocations

Syntax

delete pointerVariable;

delete [] arrayPointerVariable;

When done

using dynamic variables or arrays, do not forget to delete them.
Otherwise, you may run out of dynamic memory.

Memory Leaks

The problem in the following codes?

int a[100], i, *p, sum = 0;

for (i= 0; I < 100; i++) a[i] = I;

for (p = a; p <= &a[99]; p++)

{ sum += *p; }

cout << sum << e
ndl;
//

**********************************1

sum=0;

for (i = 0; i < 100; i++)

{ sum += *(a + i); }

cout << sum << endl;
//

**********************************2

sum =0

p = a;

for (i = 0; i < 100; i++)

{ sum += p[i]; }

cout << sum << endl;
//

***************
*******************3

sum=0

p = a;

for (i = 0; i < 100;

i++)

{ sum += *(p + i); }

cout << sum << endl;
//

**********************************4

//What is the value of
sum

at 1, 2, 3, and 4?

int * intPtr = new int [100000];

……

intPtr = new int[100];

delete
[]
intPt
r;

before the
second
new

Originally allocated memory now cannot be accessed, nor is it available for
reallocation

Array names are addresses, so are pointers

the name of array store the address of the

first element in that array

Example:

int a[
20];

//
a is equivalent to &a[0]

int *p = a;

// same as p= &a[0]

Also:

a[i] is equivalent to *(a + i)

Therefore, &a[i] = a + i

Difference between a pointer and an array

Is the

name:

pointers can be assigned different

rray name
is an

that is fixed.

Example

int a[20], b[20];

int *p = a; // same as p= &a[0]

p = b; //change the value to b, legal.

a = b; //is illegal, a is fixed value,

//can’t be reassigned

Other uses of pointers

int main( int argc,
char * argv[]);

int main (int argc, char **argv);

argc: counts the number of elements in the command line

argv
: contains command line words.

argv[0]: executables name

argv[1]: first word after the name of the executabl
e

argv[2]: second “ “ “ “ “ “ “

argv[n]: n’th word (string) in the command line.

Example:

#include <iostream>

#include <climits>

using namespace std;

int main(int ar
gc, char *argv[])

{

// What is printed?? Guess.

for (int i = 0; i < argc; i++)

cout <<
*argv[i]

<< endl;

cout<< endl << endl;

// What is printed now?

for ( i = 0; i < argc; i++)

cout <<
argv[i]
<< endl;

return

0;

}

OUTPUT:

C:
\
Desktop
\
New Folder
\
Debug>
argv_ex

This is an example

a

T

i

a

e

argv_ex

This

is

an

example

Aggregate Data Types

Predefined types not always adequate to model
the problem

When objects have multiple attributes

When objects have collections of heterogeneous elements

C++ provides
structs

and
class
es

Create new types with multiple attributes

Structures

Example:

Characteristics

has a fixed size

is ordered

elem
ents may be of different size

direct access of elements by name (not index)

struct Date {

int month, day, year;

char dayOfWeek [12];

};

structs can be nested (can contain struct objects)

Access members with

name of struct object

dot
is used a
s member selector operator

name of struct member

Date today = { 3, 4, 2005, "Tuesday");

cout << today.month;

Pointers to Structures

Pointers can be bound to
any

type

Date today = { 3, 4, 2005, "Tuesday");

Date *datePtr = &today;

Use for accessing the o
riginal location

cout << (*datePtr).day;

cin >> datePtr
-
>year;

/*==
Time.h
============================================================

This header file defines the data type Time for processing time.

B
asic operations are:

set: To set the time

display: To display the time

lessThan: To determine if one time is less than another

====================================================
===================*/

#include <iostream>

using namespace std;

struct Time

{

unsigned hour,

minute;

char AMorPM; // 'A' or 'P'

unsigned milTime; // military time equivalent

};

void set(Time & t, unsigned hours, unsigned minutes
, char AMPM);

/*
-----------------------------------------------------------------------

Set the time to a specified value.

hours, the number of hours in standard time

minutes, the number of minutes in

standard time

AMPM ('A' if AM, 'P' if PM)

Pass back: The modified Time t with data members set to the

specified values

-----------------------------------------------------------------------
*/

void display(const Time & t, os
tream & out);

/*
-------------------------------------------------------------------------

Display time t in standard and military format using output stream out.

Receive: Time t and ostream out

Output: The time t to out

Pass back: The modifie
d ostream out with a representation of t

inserted into it

------------------------------------------------------------------------
*/

void advance(Time & t, unsigned hours, unsigned minutes);

/*
-------------------------------------------
------------------------------

Increment a time by a specified value.

hours, the number of hours to add

minutes, the number of minutes to add

Pass back: The modified Time t with data members increme
nted by the

specified values

-------------------------------------------------------------------------
*/

bool lessThan(const Time & t1, const Time & t2);

/*
-------------------------------------------------------------------------

/* Determi
nes if one time is less than another time.

*

* Receive: Times t1 and t2

* Return: True if t1 < t2, false otherwise.

-------------------------------------------------------------------------
*/

/*==Time.cpp

1
--

====
=============================
=
=============

Implementations of the function members of class Time.

Prototypes are in Time.h.

=============================================================*/

#include "Time.h"

/** Utility functions
--

might be added as basic operations later
**/

int toMilitary(unsigned hours, unsigned minutes, char AMPM);

void toStandard(unsigned military,

unsigned & hours, unsigned & minutes, char & AMPM);

//
---

Definition of

set()
----------------
----------------------------

void set(Time
& t, unsigned hours, unsigned minutes, char AMPM)

{

if (hours >= 1 && hours <= 12 &&

minutes >= 0 && minutes <= 59 &&

(AMPM == 'A' || AMPM == 'P'))

{

t.hour = hours;

t.minute = minutes;

t.AMorPM = AMPM;

t.milTi
me = toMilitary(hours, minutes, AMPM);

}

else

cerr << "*** Can't set time with these values ***
\
n";

// t remains unchanged

}

//
---

Definition of display()
---------------------------------------

void display(const Time & t, ostream & out
)

{

out << t.hour << ':'

<< (t.minute < 10 ? "0" : "") << t.minute

<< ' ' << t.AMorPM << ".M. ("

<< t.milTime << " mil. time)";

}

//
---

)
-------------------------
---------------

ed hours, unsigned minutes)

{

t.milTime += 100 * hours + minutes;

unsigned milHours = t.milTime / 100,

milMins = t.milTime % 100;

milHours += milMins / 60;

milMins %
= 60;

milHours %= 24;

t.milTime = 100 * milHours + milMins;

// Now set standard time

toStandard(t.milTime, t.hour, t.minute, t.AMorPM);

}

Continued below
;

//
Time.cpp =2=

//
---

Definition of lessThan()
-----------------------
-----------
----------

bool lessThan(const Time & t1, const Time & t2)

{

return (t1.milTime < t2.milTime);

}

//
-----

DEFINITIONS OF UTILITY FUNCTIONS
-------

int toMilitary (unsigned hours, unsigned minutes, char
AMPM)

/*
-----------------------------------------
-----------
---------------------

Convert standard time to military time.

Return: The military time equivalent

------------------------------------------------------
-------------------
*/

{

if (hours == 12)

ho
urs = 0;

return hours * 100 + minutes + (AMPM == 'P' ? 1200
: 0);

}

void toStandard(unsigned military,

unsigned & hours, unsigned & minutes,
char & AMPM)

/*
----------------------------------------------------
---------------------

Con
vert military time to standard time.

Receive: military, a time in military format

Return: hours, minutes, AMPM
--

equivalent
standard time

------------------------------------------------------
-------------------
*/

{

hours = (military / 100) %
12;

if (hours == 0)

hours = 12;

minutes = military % 100;

AMPM = (military / 100) < 12 ? 'A' : 'P';

}

Review this chapter. Make sure you understand it. Then
, solve the text quizzes
3.2, 3.3, 3.4, and 3.5. Make sure you understand them.