CS102 Introduction to Computer Programming

Download Report

Transcript CS102 Introduction to Computer Programming

CS102
Introduction to Computer
Programming
Chapter 9 Pointers
Topics for Discussion
• Getting the Address of a
Variable
• Pointer Variables
• The Relationship
Between Arrays and
Pointers
• Pointer Arithmetic
• Initializing Pointers
• Comparing Pointers
• Pointers as Function
Parameters
• Dynamic Memory
Allocation
• Returning Pointers from
Functions
Getting the Address of a Variable
• Each byte of memory has a unique address
• A variables address is the address of the
first byte allocated to that variable.
• Putting an & in front of a variable name
returns its address
&Letter = 0006
&Number = 0004
&Real = 0000
0000
0001
4 bytes(float)
0002
0003
0004
0005
2 bytes(int)
0006
1 byte char
Concept - In C++, it is possible to get the memory address of a
variable
Program 9-1
/* This program uses the & operator to
determine a variable’s address and
the sizeof operator to determine its
size.*/
#include <iostream>
Using namespace std;
void main(void)
{
int X = 25;
cout << "The address of X is " <<
&X << endl;
cout << "The size of X is " <<
sizeof(X) << " bytes\n";
cout << "The value in X is " << X
<< endl;
}
X
0x8f00
0x8f01
0x8f02
0x8f03
0x8f04
0x8f05
0x8f06
0x8f07
0x8f08
0x8f09
0x8f0a
0x8f0b
0x8f0c
0x8f0e
0x8f0f
25
Program Output
The address of X is 0x8f05
The size of X is 4 bytes
The value in X is 25
Pointer Variables
• Data stored in other variables can be manipulated
by pointer variables
– Working directly with memory locations that regular
variables don't give you access to.
– Working with strings and arrays
– Creating new variables during program execution
– Creating arbitrarily-sized lists of values in memory
Concept - Pointer variables, which are often just called
pointers, are designed to hold memory addresses
Pointer Variables
• Pointer variables are defined by placing an * in
front of the variable name.
int *ptr;
// ptr is a pointer to an
// integer variable
• You use a pointer variable to hold the address of
a variable.
int num = 25;
ptr = &num;
// ptr contains the address
// of the first byte of num
cout <<num <<", " <<ptr;
//display is 25, 0x7e00
Program 9-2
/* This program stores the address of a
X
variable in a pointer.*/
#include <iostream.h>
void main(void)
Ptr
{
int X = 25;
int *Ptr;
Ptr = &X; // Store the address of X in Ptr
cout << "The value in X is " << X << endl;
cout << "The address of X is " << Ptr <<
endl;
Program Output
}
The value in X is 25
The address of X is 0x8f05
0x8f00
0x8f01
0x8f02
0x8f03
0x8f04
0x8f05
0x8f06
25
0x8f07
0x8f08
0x8f09
0x8f0a
0x8f0b
0x8f0c 0x8f05
0x8f0e
0x8f0f
Indirection and Dereference
• The * is also the indirection operator and
dereferences a pointer variable
ptr = &num;
*ptr =30
//note: * used differently here then when
declaring a pointer variable
cout << num <<", " << *ptr;
//display 30, 30
• Working with a dereferenced pointer
variable is like working with the variable it
points to.
Program 9-3
/* This program demonstrates the use of
the indirection operator.*/
#include <iostream.h>
void main(void)
{
int X = 25;
int *Ptr;
Ptr = &X; // Store the address of X in
Ptr
cout << "Here is the value in X, printed
twice:\n";
cout << X << " " << *Ptr << endl;
*Ptr = 100;
cout << "Once again, here is the value
in X:\n";
cout << X << " " << *Ptr << endl;
}
X
Ptr
0x8f00
0x8f01
0x8f02
0x8f03
0x8f04
0x8f05
0x8f06
25
0x8f07 100
0x8f08
0x8f09
0x8f0a
0x8f0b
0x8f0c 0x8f05
0x8f0e
0x8f0f
Program Output
Here is the value in X, printed twice:
25 25
Once again, here is the value in X:
100 100
Program 9-4
#include <iostream.h>
void main(void)
{
short X = 25, Y = 50, Z = 75;
short *Ptr;
cout << "Here are the values of X, Y,
and Z:\n";
cout << X << " " << Y << " " << Z <<
endl;
Ptr = &X; // Store the address of X in
Ptr
*Ptr *= 2; // Multiply value in X by 2
Ptr = &Y; // Store the address of Y in
Ptr
*Ptr *= 2; // Multiply value in Y by 2
Ptr = &Z; // Store the address of Z in
Ptr
*Ptr *= 2; // Multiply value in Z by 2
cout << "Once again, here are the
values of X, Y, and Z:\n";
cout << X << " " << Y << " " << Z <<
endl;
}
X
Y
Z
Ptr
0x8f00
0x8f01
0x8f02
0x8f03
0x8f04
0x8f05
0x8f06
0x8f07
0x8f08
0x8f09
0x8f0a
0x8f0b
0x8f0c
0x8f0e
0x8f0f
25
50
50
100
75
150
0x8f02
0x8f04
0x8f00
Program Output
Here are the values of X, Y, and Z:
25 50 75
Once again, here are the values of
X, Y , and Z:
50 100 150
The Relationship Between
Arrays and Pointers
• An array name without brackets and
subscripts is a pointer to the array.
int array[ ] {1,2,3,4,5};
cout <<array <<", " <<*array;
//display 0x07e00, 1
cout << (array+1) <<", " <<*(array+1)
//display 0x7e04, 2
(run program 8-7)
Concept - Arrays names can be used as pointers and vice-versa
Program 9-5
// This program shows an array name
// being dereferenced with the *
// operator.
#include <iostream.h>
void main(void)
{
short Numbers[] = {10, 20, 30, 40,
50};
Numbers
0x8f00
0x8f01
0x8f02
0x8f03
0x8f04
0x8f05
0x8f06
0x8f07
0x8f08
0x8f09
0x8f0a
0x8f0b
0x8f0c
0x8f0e
0x8f0f
10
20
30
40
50
cout << "The first element of the
array is ";
cout << *Numbers << endl;
}
Program Output
The first element in the array is
10
Program 9-7
/* This program uses subscript
notation with a pointer and
pointer notation with an array
name.*/
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
float Coins[5] = {0.05, 0.1,
0.25, 0.5, 1.0};
float *FloatPtr; // Pointer to a
float
int Count;
// Array index
FloatPtr = Coins; // FloatPtr
now points to Coins array
cout.precision(2);
cout << "Here are the values in
the Coins array:\n";
for (Count = 0; Count < 5;
Count++)
cout << FloatPtr[Count]
<< " ";
cout << "\nAnd here they are
again:\n";
for (Count = 0; Count < 5;
Count++)
cout << *(Coins + Count) <<
" ";
cout << endl;
}
Program continues
Here are the values in the Coins array:
0.05 0.1 0.25 0.5 1
And here they are again:
0.05 0.1 0.25 0.5 1
Program 9-8
// This program uses the
address of each element in
the array.
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
float Coins[5] = {0.05, 0.1,
0.25, 0.5, 1.0};
float *FloatPtr; // Pointer to a
float
int Count;
// Array index
cout.precision(2);
cout << "Here are the values
in the Coins array:\n";
for (Count = 0; Count < 5;
Count++)
{
FloatPtr =
&Coins[Count];
cout << *FloatPtr
<< " ";
}
cout << endl;
}
Program Output
Here are the values in the
Coins array:
0.05 0.1 0.25 0.5 1
Pointer Arithmetic
• Integers may be added or subtracted from
pointer variables.
int *ptr, num, array[4];
ptr +=1; ptr++; ptr = ptr+1;
ptr-=1; ptr--; ptr = ptr -1;
ptr = ptr+(&array[1] - &array[0]);
• You can not perform multiply or divide
operations on pointers
Concept - Certain mathematical operations may be performed
on pointers
Program 9-9
// This program uses a pointer to display
the contents of an integer array.
#include <iostream>
using namespace std;
void main(void)
{
int Set[8] = {5, 10, 15, 20, 25, 30, 35,
40};
int *Nums, Index;
Nums = Set;
cout << "The numbers in Set are:\n";
for (Index = 0; Index < 8; Index++)
{
cout << *Nums << " ";
Nums++;
}
cout << "\nThe numbers in Set backwards
are:\n";
for (Index = 0; Index < 8; Index++)
{
Nums--;
cout << *Nums << " ";
}
}
Program Output
The numbers in Set are:
5 10 15 20 25 30 35 40
The numbers in Set backwards
are:
40 35 30 25 20 15 10 5
Initializing Pointers
• A pointer is defined for a particular data
type .
– The following are legal statements
int num, *ptr = &num;
int num[4], *ptr = num;
– These are illegal statements
int *ptr = num; int num;
float num; int *ptr = &num;
Concept - Pointers may be initialized with the address of an
existing object.
Comparing Pointers
• Relational operators may be used to compare
pointer values.
if (&array[1] >&array[0])
True
if (array < &array[4])
True
if (array = = &array[0])
True
if (&array[2] != &array[3])
True
for (int *num = array; num < &array[5]; num++)
cout <<*num <<endl;
Note: the * above is not a indirection in this case!
Concept - If one address comes before another address in
memory, the first address is considered < the second
Program 9-10
// This program uses a pointer to
display the contents of an integer
array.
#include <iostream.h>
void main(void)
{
int Set[8] = {5, 10, 15, 20, 25, 30,
35, 40};
int *Nums = Set; // Make Nums
point to Set
cout << "The numbers in Set
are:\n";
cout << *Nums << " "; // Display
first element
while (Nums < &Set[7])
{
Nums++;
cout << *Nums << " ";
}
cout << "\nThe numbers in Set
backwards are:\n";
cout << *Nums << " "; // Display
last element
while (Nums > Set)
{
Nums--;
cout << *Nums << " ";
}
}
Program Output
The numbers in set are:
5 10 15 20 25 30 35 40
The numbers in set backwards are:
40 35 30 25 20 15 10 5
Pointers as Function Parameters
• Passing to a function the pointer to a
variable is like using a reference parameter.
int Number = 2;
cout <<DoubleValue(&Number)
cout <<", " <<Number;
//display is 4, 4
int DoubleValue (int *Val)
{return *Val *=2;}
Concept - A pointer can be used as a function parameter
Program 9-11
/* This program uses two functions that
accept addresses of variables as
arguments.*/
#include <iostream.h>
// Function prototypes
void GetNumber(int *);
void DoubleValue(int *);
void main(void)
{
int Number;
GetNumber(&Number); // Pass
address of Number to GetNumber
DoubleValue(&Number); // and
DoubleValue.
cout << "That value doubled is " <<
Number << endl;
}
Program Output
Enter an integer number: 10 [Enter]
That value doubled is 20
/* Definition of GetNumber. The
parameter, Input, is a pointer. This
function asks the user for a number.
The value entered is stored in the
variable pointed to by Input.*/
void GetNumber(int *Input)
{
cout << "Enter an integer number: ";
cin >> *Input;
}
/* Definition of DoubleValue. The
parameter, Val, is a pointer. This
function multiplies the variable pointed
to by Val by two.*/
void DoubleValue(int *Val)
{
*Val *= 2;
}
Program 9-12
/*This program demonstrates that a
pointer may be used as a parameter to
accept the address of an array. Either
subscript or pointer notation may be
used.*/
#include <iostream>
#include <iomanip>
using namespace std;
// Function prototypes
void GetSales(float *);
float TotalSales(float *);
void main(void)
{
float Sales[4];
GetSales(Sales);
cout << fixed << showpoint;
cout << setprecision(2);
cout << "The total sales for the year
are $";
cout << TotalSales(Sales) << endl;
}
/* Definition of GetSales. This function
uses a pointer to accept the address of
an array of four floats. The function
asks the user to enter the sales figures
for four quarters, and stores those
figures in the array. (The function
uses subscript notation.)*/
void GetSales(float *Array)
{
for (int Count = 0; Count < 4; Count++)
{
cout << "Enter the sales figure for
quarter ";
cout << (Count + 1) << ": ";
cin >> Array[Count];
}
}
Program continues
// Definition of TotalSales. This function
uses a pointer to accept the address of
an array of four floats. The function
gets the total of the elements in the
array and returns that value. (Pointer
notation is used in this function.)
float TotalSales(float *Array)
{
float Sum = 0.0;
for (int Count = 0; Count < 4; Count++)
{
Sum += *Array;
Array++;
}
return Sum;
}
Program Output
Enter the sales figure for quarter 1:
10263.98 [Enter]
Enter the sales figure for quarter 2:
12369.69 [Enter]
Enter the sales figure for quarter 3:
11542.13 [Enter]
Enter the sales figure for quarter 4:
14792.06 [Enter]
The total sales for the year are
$48967.86
Dynamic Memory Allocation
• The new operator requests the computer to
allocate a block of memory for a particular
data type
int *Iptr;
Iptr = new int;
• A value can be stored in this new variable
by dereferencing the pointer
*Iptr = 25:
Concept - Variables may be created and destroyed while the
program is running
Dynamically Allocating Arrays
• You can dynamically
• If you ask for more
created an array while a
memory than is
program is running
available the null
pointer is returned
Iptr = new int[10];
for (int count =0; count <
10; count++)
Iptr [count] =1;
Iptr = new int[100];
if (Iptr == Null)
exit;
Concept - A pointer that contains the address 0 is called a null
pointer
Program 9-13
/* This program totals and averages
the sales figures for any number of
days. The figures are stored in a
dynamically allocated array.*/
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
float *Sales, Total = 0, Average;
int NumDays;
cout << "How many days of sales
figures do you wish ";
cout << "to process? ";
cin >> NumDays;
Sales = new float[NumDays]; //
Allocate memory
if (Sales == NULL) // Test for null pointer
{
cout << "Error allocating
memory!\n";
return;
}
// Get the sales figures from the user
cout << "Enter the sales figures
below.\n";
for (int Count = 0; Count < NumDays;
Count++)
{
cout << "Day " << (Count + 1) <<
": ";
cin >> Sales[Count];
}
// Calculate the total sales
for (Count = 0; Count < NumDays;
Count++)
{
Total += Sales[Count];
}
Program continues
// Calculate the average sales per
day
Average = Total / NumDays;
// Display the results
cout.precision(2);
cout.setf(ios::fixed |
ios::showpoint);
cout << "\n\nTotal Sales: $" <<
Total << endl;
cout << "Average Sales: $" <<
Average << endl;
// Free dynamically allocated
memory
delete [] Sales;
}
Program Output
How many days of sales figures
do you wish to process? 5
[Enter]
Enter the sales figures below.
Day 1: 898.63 [Enter]
Day 2: 652.32 [Enter]
Day 3: 741.85 [Enter]
Day 4: 852.96 [Enter]
Day 5: 921.37 [Enter]
Total Sales: $4067.13
Average Sales: $813.43
Releasing Memory
• When you are finished with a dynamically
allocated variable, its memory can be
released for future use.
Iptr = new int;
delete Iptr;
Iptr = new int[10];
delete [ ] Iptr;
• Failing to release memory (memory leaks)
can result in out of memory errors and
system failures
• Only use delete with pointer variables that
were assigned by the new operator.
Returning Pointers from Functions
• A function can be defined to return a
pointer.
int * GetNumPtr (int Array, int elm, int Num)
for (int R=0; R<elm; R++)
if (Array[R] = = Num)
return &Array[R];
return Null;
Concept - Functions can return pointers, but you must be sure
the object the pointer references still exists
Summary
•
•
•
•
The * is used to define a pointer variable
The * is used to de-reference a pointer variable
The * is used to multiply non-pointer variables
The & is used to reference the address of a
variable
• Incrementing a pointer increases its value by the
size of the data type it references
• The name of an array without the subscript is a
reference to the starting address of the array
Sample Pointer Operations
int *ptr;
//Defines a pointer for an integer value
int num, *ptr =&num; //Defines a ptr and initializes it to the address
//of an integer
ptr = &num;
//Assigns the address of num to ptr
ptr = Array;
//Assigns the address of Array to ptr
(*ptr)++;
//Increments the value located in memory
// at the address contained in ptr by one
ptr++;
//Increments the address contained in ptr by
//the size of one data type
func(&num);
//Passes the address of a variable to a function
int * func(void)
//Defines a function that returns an address
ptr = new int;
//Allocates memory for an integer variable
ptr = new int [10 ];
//Allocates memory for an integer array
delete ptr;
//Returns the memory back to the system