Sei sulla pagina 1di 46

1

The Relationship between Pointers & Arrays

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
2

The Relationship between Pointers & Arrays


• An array name without the subscript notation ([]) is
considered as a constant pointer that always points to the
first element in the array.

• Like other constant pointers, the array name is associated


with a particular memory location and that association
cannot be changed by statements in the program.

• That is why arrays are passed by reference by default.


Because, their names are initially pointers. Since pointers
pass addresses of variables, then arrays do too.

• That is also why individual elements of an array are by


default passed by value.

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
3

• Initializing a pointer to point to an array is


equivalent to initializing the pointer to point to
the first element of the array.

• In both cases, the pointer contains the


address of the first element of the array.

• Pointers can be used to do any operations


involving array subscribing.

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
• Define an array v[ 5 ] and a pointer vPtr 4

– To set them equal to one another use:


– vPtr = v;
• The array name (v) is actually the address of first element of the array v[ 5 ]
– vPtr = &v[ 0 ]
• Explicitly assigns vPtr to address of first element of v
3000 3004 3008 3012 3016

V[0] V[1] V[2] V[3] V[4]

Pointer variable vPtr


Array v and a pointer variable vPtr that points to v
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
5
Example (1)

int A[5];
int B[10];

int *Ptr1=A; //Ptr1 points to A[0]


//int *Ptr1=&A[0]; Ptr1 points to A[0]

int *Ptr2=B; //Ptr2 points to B[0]

int *Ptr3=&B[0]; //Ptr3 points to B[0]

int *Ptr4=&A[4]; //Ptr4 points to A[4]

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
6

Example (2)
int b[5], *bPtr;

b++; //compiler error


//b=b+1; i.e. &b[0]=&b[0]+1;

bPtr=b;
Is equivalent to:
bPtr=&b[0];

b=bPtr; //compiler error


//even though b and bPtr both point to the same location in
memory, the statement gives an error (because array name b is
a constant pointer)

if (b==&b[0]) …//always true


© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
7

Example (3)

#include<iostream.h> xpointer=&z;
void main(){ cout<<*xpointer<<endl;//1
int x=1, z=1, xx[10]={10,20,30}; cout<<xpointer<<endl<<endl;
//0x0012FF78
int y[5]={11,22,33,44};
if(xx==&xx[0])
int *xpointer; cout<<"Array names are
xpointer=xx; constant pointers"<<endl;
cout<<*xpointer<<endl;//10 //the condition evaluates to //true
cout<<xpointer<<endl<<endl;
//0x0012FF50 xx=&y[0];
//error: attempt to change the
xpointer=&xx[0]; //address of a constant pointer
cout<<*xpointer<<endl;//10
cout<<xpointer<<endl<<endl; }
//0x0012FF50
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
8
Accessing array elements with pointers
(pointer subscript notation)
The array name (b) is actually the address of
first element of the array b[ 5 ]

bPtr = &b[ 0 ]
bPtr = b;

Array subscript notation b[ 3 ]


Pointer subscript notation bPtr[ 3 ]

bPtr[ 3 ] same as b[ 3 ]

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
9
Accessing array elements with pointers
(pointer offset notation)
int b[5], *bPtr = b;
•The element b[2] can be alternatively referenced with the pointer
operation *(bPtr + 2), where 2 is the offset to the pointer. The
offset value is identical to the array subscript.
•When using pointers to reference the values of array elements as
in the above notation, it is referred to as the pointer/offset
notation.

b[ 0 ] same as *( b + 0 )
b[ 3 ] same as *( b + 3 )
Element b[ n ] can be accessed by *( b + n )
b[ 0 ] same as *( bPtr + 0 )
b[ 3 ] same as *( bPtr + 3 )
Element b[ n ] can be accessed by *( bPtr + n )

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
10

• The address of the array element (&b[2]) can be


alternatively referenced with the pointer operation
bPtr + 2.

• Pointer/offset notation
&b[ 0 ] same as bPtr + 0
&b[ 3 ] same as bPtr + 3
Pointer/offset notation where the pointer
is the array name
&b[ 0 ] same as b + 0
&b[ 3 ] same as b + 3

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
11
Outline

#include <iostream.h> Example4(the relationship between


int main() pointers and arrays)
{
int b[] = { 10, 20, 30, 40 };
int *bPtr;
Using array
bPtr = b; // set bPtr to point to arraysubscript
//bptr=&b[0] notation.
for ( int i = 0; i < 4; i++ )
cout << "b[" << i << "] = " << b[ i ] << '\n';

for ( int j = 0; j < 4; j++ )


cout << "bPtr[" << j << "] = " << bPtr[ j ] <<
'\n'; Using pointer
subscript notation.

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
12
Outline

#include <iostream.h> Example4(the relationship between


int main() pointers and arrays)
{
int b[] = { 10, 20, 30, 40 };
int *bPtr = b; // set bPtr to point to array

for ( int offset1 = 0; offset1 < 4; offset1++ )


cout << "*(b + " << offset1 << ") = "
<< *( b + offset1 ) << '\n';
Using array name and
for ( int offset2 = 0; offset2 < 4; pointer/offset
offset2++ )
notation.
cout << "*(bPtr + " << offset2 << ") = "
<< *( bPtr + offset2 ) << '\n';
Using bPtr and
pointer/offset
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
notation.
13

Example (5)

int b[5]={12,7,4,11,16}, *bPtr=b;

b[3] //11
can be replaced with
*(bPtr+3) //*(&b[0]+3)
Or with
*(b+3) //*(&b[0]+3) is this equal to *b+3;?

*bPtr+3 //*(&b[0])+3=15
is equivalent to
b[0]+3 //12+3=15

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
14

*bPtr+3
is equivalent to
b[0]+3

*(bPtr+3)
is equivalent to
b[3]

&b[3]
is equivalent to
bPtr+3
And is equivalent to:
b+3

bPtr=&b[2];
cout<<*(bPtr+2); //prints b[4]
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
15
Pointers Comparison

• Pointers of the same data type can be compared


using equality and relational operators.

• The most common operation is to use == and != to


determine if 2 pointer variables point to the same
memory location or not.

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
16

Example (1)

int *iPtr, *jPtr;


if(iPtr == jPtr)
//returns true iff the address in iPtr is the same as the address in jPtr.

int *nPtr;
double *dPtr;
if(nPtr = = dPtr)
//error: not valid statement because the 2 pointers are of different data types

The null address can be compared with any pointer variable.


if(nPtr==0)
if(dPtr==0)
//Both of the above statements are valid/legal statements
//The expressions evaluate to true if both pointers were pointing to nothing in
memory.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
17

Example (2)

int A[5], B[10];


int *Ptr1=A, *Ptr2=B;
int *Ptr3=&B[0];
int *Ptr4=&A[4];

if (A==B) //if (&A[0]= =&B[0])


cout<<“A and B are same values”<<endl;
else
cout<<“A and B are different values”<<endl;

if (Ptr1==A)
cout<<“Ptr1 and A are same values”<<endl;
else
cout<<“Ptr1 and A are different values”<<endl;

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
18

if (Ptr2 != Ptr3)
cout<<“Ptr2 and Ptr3 are different values”<<endl;
else
cout<<“Ptr2 and Ptr3 are same values”<<endl;

if (Ptr1 < Ptr4)


cout<<“Ptr1 is first in memory than Ptr4”<<endl;
else
cout<<“Ptr1 is not first in memory than Ptr4”<<endl;

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
19

The output of the previous code (e.g. 2) segment is:

A and B are different values


Ptr1 and A are same values
Ptr2 and Ptr3 are same values
Ptr1 is first in memory than Ptr4

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
20

Pointers Assignment
• Pointer variables can be assigned the values of other pointer
variables that are of the same data type

• If jPtr and iPtr are 2 pointers of the same data type, then the
result of the expression
jPtr = iPtr; is that the value of iPtr will be copied to jPtr so
that they both have the same memory location.

• the result of the expression


*jPtr = *iPtr; is that the value pointed to by jPtr will be
replaced by the value pointed to by iPtr so that the variables
to which the pointers are pointing will both have the same
value.

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
21

11 i
22 11 j
*iPtr
... *jPtr = *iPtr;
0xbffffd20 iPtr
*jPtr
0xbffffd24 jPtr
Before the Assignment

11 i After the Assignment


jPtr=iPtr
22 11 j
*iPtr
...
*jPtr 0xbffffd20 iPtr
0xbffffd20 jPtr
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
22

• Pointers of the same type can be assigned to each


other
– If not the same type, a cast operator must be used
– Exception: pointer to void (type void *)
• Generic pointer, represents any type
• No casting needed to convert a pointer to void pointer

Example:
int *ptr1;
void *ptr2;
ptr2 = ptr1;
ptr1 = (int *)ptr2;

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
23

Pointer operations (Increments ++ and Decrements--)

• A pointer may be incremented (++) or decremented (--).

• An integer may be added to a pointer (+ or +=).

• An integer may be subtracted from a pointer (- or -=).

• One pointer may be subtracted from another.

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
24

Example

int A[4] = {10,20,30,40};


int *Ptr = A;
cout<<“Original address stored in pointer: ”<<Ptr<<endl;
cout<<“Original value pointed to by pointer: ”<<*Ptr<<endl;
++Ptr;
cout<<“Address stored in pointer after increment:”<<Ptr<<endl;
cout<<“Value pointed to by pointer after increment: ”<<*Ptr<<endl;
--Ptr;
cout<<“Address stored in pointer after decrement: ”<<Ptr<<endl;
cout<<“Value pointed to by pointer after decrement:
”<<*Ptr<<endl;

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
25

10 A[0]
20 A[1]
30 A[2]
40 A[3]
50 A[4]
Ptr

Before the Increment

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
26

10 A[0]
20 A[1]
30 A[2]
40 A[3]
50 A[4]
Ptr

After the Increment

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
27

10 A[0]
20 A[1]
30 A[2]
40 A[3]
50 A[4]
Ptr

After the Decrement

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
28

Operator Precedence
Operators Associativity

Parenthesis ( ) [ ] Left to Right

Unary
+ - ++ -- ! * & (type) Right to Left

/ % Left to Right

+ - Left to Right

< <= > >= Left to Right

== != Left to Right

&& Left to Right

|| Left to Right

= += -= *= /= %= Right to Left

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
29

Addition on Pointers
• The expression Ptr + i results in a pointer to the ith
object beyond the object to which Ptr points.

• i, here is also called the offset.

• The expression *(Ptr + i) displays the contents of


the offset address (the new value being pointed to)

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
30
Example
int x=2;
int *Ptr = &x;
cout<<*(Ptr + 2)<<endl; //50
cout<<*Ptr<<endl; //2
Ptr+=2;
cout<<*Ptr; //50

...
...
Before adding 2 to the pointer
2 x

After adding 2 to the pointer ...


50 Ptr+= 2
Ptr
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
31

• When an integer is added to a pointer, the pointer is not


simply incremented by the value of the integer, but by
that integer times the size of the object to which the
pointer refers.

New Address = Old Address + (integer * size of object)

• An integer may be represented by 2 or 4 bytes. A float is


represented by 4 bytes. A double is represented by 8
bytes. A character is represented by 1 byte.

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
32
Example

• On a machine with 4-byte integer representation, v array


is defined.
int v[5]; 3000 3004 3008 3012 3016
int vPtr=v;
vPtr V[0] V[1] V[2] V[3] V[4]
vptr+=3;
//The above statement produces the address 3012 (3000
+ (3*4))
//vPtr now points to v[3]
//if the array was defined on a machine with 2-byte
integer representation, the new address would be 3006
(3000 + (3*2))

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
33

//if this increment statement is used


vPtr++;
//or if this increment statement is used
//++vPtr;

3000 3004 3008 3012 3016

vPtr V[0] V[1] V[2] V[3] V[4]

//the result would be that the pointer is incremented


to point to the next location in the array.
// the new address is: 3012 + (1*4) = 3016

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
34

Subtraction on Pointers

• The expression Ptr - i results in a pointer to the ith


object prior to the object to which Ptr points.

• i, here is also called the offset.

• The expression *(Ptr - i) displays the contents of


the offset address (the new value being pointed to)

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Example 35

int x=2;
int *Ptr = &x;
cout<<*(Ptr - 2)<<endl;
cout<<*Ptr<<endl;
Ptr-=2;
cout<<*Ptr;

After subtracting 2 from Ptr


400 Ptr-=2

Before subtracting 2 from Ptr ...


2 x
...
...
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Ptr
36

• When an integer is subtracted from a pointer, the pointer


is not simply decremented by the value of the integer,
but by that integer times the size of the object to which
the pointer refers.

New Address = Old Address - (integer * size of object)

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
37

Continued Example of v Array

3000 3004 3008 3012 3016


vptr-=3;
vPtr V[0] V[1] V[2] V[3] V[4]

//The above statement produces the address 3004


(3016 - (3*4))
//vPtr now points to v[1]

//if the array was defined on a machine with 2-


byte integer representation, the new address would
be 3010 (3016 - (3*2))
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
38

//if this decrement statement is used


vPtr--;
//or if this increment statement is used
//--vPtr;
3000 3004 3008 3012 3016

vPtr V[0] V[1] V[2] V[3] V[4]

//the result would be that the pointer is decremented to point


to the prior location in the array.
// the new address is: 3004 - (1*4) = 3000

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
39

Subtracting Two Pointers

• Pointer variables may be subtracted from one another.

• Subtraction Result = Difference/size of object to which the


pointer refers

• If vPtr contains the address 3000 and v2Ptr contains the address
3008, then the statement: x = v2Ptr – vPtr;
would assign to the variable x the number of array elements
from vPtr to v2Ptr. x equals 2 not 8.

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
40

Example on Arithmetic Operations Performed on


Pointers of Different Data Types
int x;
int *y;
y=&x;
y++; //increases y by 2 (1*2)
y+=5; //increases y by 10 (5*2)
2 byte integer
double z;
double *w;
w=&z;
w--; //decreases w by 8 (1*8)
w-=5; //decreases w by 40 (5*8)
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
8 byte double
41
int b[7]={12,4,5,1,3,50, 44};
int *bPtr=&b[2];
cout<<*(bPtr+2)<<endl; //prints b[4], 3
cout<<*(++bPtr)<<endl; //increments bPtr and displays the new
//value, 1
cout<<*bPtr<<endl; //displays 1

cout<<*(bPtr++)<<endl; //increments bPtr & displays the old


//value, 1
cout<<*bPtr<<endl; //displays 3

cout<<++(*bPtr)<<endl; //increments b[4] and displays the new


//value, 4
cout<<b[4]<<endl; //displays 4
cout<<(*bPtr)++<<endl; //increments b[4] and displays the old
//value, 4
cout<<b[4]<<endl; //displays 5
}//end of 1992–2004
© Copyright main by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
42
Example: sum array

#include<iostream.h>
int sumArrayStandard(int [], int);
void sumArrayReference(int [ ], int, int *);
int sumArrPtrNotation(int *);

//using standard array notation


int sumArrayStandard(int X[], int size){
int sum=0;
for (int i=0;i<size;i++) sum+=X[i];
return sum;
}

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
43

//using pointer notation


void sumArrayReference (int a[], int size, int *sumPtr)
{
*sumPtr=0;

for (int I=0; I<size; I++)


*sumPtr+=a[I];

cout<<*sumPtr<<endl;
}
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
44
//using pointer notation
int sumArrPtrNotation(int *X){
int *xptr;
int sum=0;

for (xptr=&X[0]; xptr<=&X[4]; xptr++)


//for (xptr=X; xptr<=X+4; xptr++)
sum+=*xptr;

/*for (int i=0,xptr=X; i<=4; i++)


sum+=*(xptr+i); */

return sum;
} © Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
45

void main(){
int Y[5]={1,2,3,4,5};
int sum;

cout<<sumArrayStandard(Y,5)<<endl;
//displays 15

sumArrayReference(Y,5,&sum);
//displays 15

cout<<sumArrPtrNotation(Y)<<endl;
//displays 15

}//end of main

© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
46
Example

int x[] = {1, 2, 3, 4};


int i;
int *xptr;
for (i=0, xptr=x ; i<=3; i++)
cout << *(xptr+i) << endl;

for (xptr=x ; xptr<=&x[3]; xptr++)


cout << *xptr << endl;

for (xptr=x; *xptr<=x[3]; xptr++)


cout << *xptr << endl;
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.

Potrebbero piacerti anche