#include <iostream> using namespace std; int main() { int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Addresses"; cout << "\n Number : " << Number; cout << "\npNumbers : " << pNumbers; return 0; }
This would produce:
Addresses Number : 1245020 pNumbers : 1245020
In other words, pNumbers points to the beginning of the
array. As you can see from the previous result, pNumbers holds an address and
not a value, that is, not the value of the first member of the array. Since
pNumbers points to the first member of the array (by virtue of its relationship
to the array, which we have demonstrated by showing that pNumbers and Number
hold the same value, which is the same as the address of the first member of the
array), to get the value that pNumbers holds, we learned, when studying pointers,
that you must use the asterisk operator. Therefore, number[0], which is the
value of the first member of the array, is the same as *pNumbers, which is the
value of the first member of the array. This can be verified in the following
program:
#include <iostream> using namespace std; int main() { int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Values"; cout << "\n number[0] : " << number[0]; cout << "\n*pNumber : " << *pNumbers; return 0; }
This would produce:
Values number[0] : 31 *pNumber : 31
We saw already that pNumbers is an address; it is not a
value. In the same way, Number is an address. To get the value of a member of
the Number array, we know that, using the square brackets, we can provide the
index of the member we want and retrieve its value. In the same way, using a
pointer that has been initialized to an array variable, we can use the square
bracket and the index of the member whose value we want to retrieve. This is
demonstrated in the following program:
#include <iostream> using namespace std; int main() { int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Addresses"; cout << "\n Number : " << Number; cout << "\npNumbers : " << pNumbers; cout << "\n\nValues"; cout << "\n Number [0] : " << number[0]; cout << "\npNumbers[0] : " << pNumbers[0]; cout << "\n Number [1] : " << number[1]; cout << "\npNumbers[1] : " << pNumbers[1]; return 0; }
This would produce:
Addresses Number : 1245020 pNumbers : 1245020 Values Number [0] : 31 pNumbers[0] : 31 Number [1] : 28 pNumbers[1] : 28
At this time, we know how to get the address of the first
member of the array, with either Number or pNumbers. To get the address of the
second member of the array, we increment that address value, as in Number+1.
Since Number is an address and not a value, adding 1 to it adds the size of its
type, in this case 4 bytes, in order to get to the next address. In the same
way, using a pointer that has been initialized with an array, to get the address
of the next member of the array, simply increment its name. Here is an example:
#include <iostream> using namespace std; int main() { int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Addresses"; cout << "\n Number : " << Number; cout << "\npNumbers : " << pNumbers; cout << "\n Number +1 : " << Number+1; cout << "\npNumbers+1 : " << pNumbers+1; cout << "\n Number +2 : " << Number+2; cout << "\npNumbers+2 : " << pNumbers+2; return 0; }
This would produce:
Addresses Number : 1245020 pNumbers : 1245020 Number +1 : 1245024 pNumbers+1 : 1245024 Number +2 : 1245028 pNumbers+2 : 1245028
Now we know that by writing pNumbers or pNumbers+n, we
get the address of the member that "lives" at pNumbers or pNumbers+n. We already saw
that, by writing *pNumbers, we can get the value of the first member of the
array. When writing *pNumbers, we are in fact asking the compiler to retrieve
the value that pNumbers points to. If we want to get the value of the next
member of the array, we must first give its address, which is done by adding the
index of the member of the array to pNumbers. Once we have communicated the
address, we use the asterisk operator to retrieve the actual value of the member
of the array. Because the asterisk operator has a higher precedence
than the addition operator, to get the address before the value, you must use
parentheses to delimit the operation:
#include <iostream> using namespace std; int main() { int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Values - Using the Array"; cout << "\n number[0]: " << number[0]; cout << "\n number[1]: " << number[1]; cout << "\n number[2]: " << number[2]; cout << "\n number[3]: " << number[3]; cout << "\n number[4]: " << number[4]; cout << "\n\nValues - Using the Pointer - No Parentheses"; cout << "\n*pNumbers: " << *pNumbers; cout << "\n*pNumbers+1: " << *pNumbers+1; cout << "\n*pNumbers+2: " << *pNumbers+2; cout << "\n*pNumbers+3: " << *pNumbers+3; cout << "\n*pNumbers+4: " << *pNumbers+4; cout << "\n\nValues - Using the Pointer - With Parentheses"; cout << "\n*pNumbers: " << *pNumbers; cout << "\n*(pNumbers+1): " << *(pNumbers+1); cout << "\n*(pNumbers+2): " << *(pNumbers+2); cout << "\n*(pNumbers+3): " << *(pNumbers+3); cout << "\n*(pNumbers+4): " << *(pNumbers+4); return 0; }
This would produce:
Values - Using the Array number[0]: 31 number[1]: 28 number[2]: 31 number[3]: 30 number[4]: 31 Values - Using the Pointer - No Parentheses *pNumbers: 31 *pNumbers+1: 32 *pNumbers+2: 33 *pNumbers+3: 34 *pNumbers+4: 35 Values - Using the Pointer - No Parentheses *pNumbers: 31 *(pNumbers+1): 28 *(pNumbers+2): 31 *(pNumbers+3): 30 *(pNumbers+4): 31 Press any key to continue...
Therefore, as long as you increment the address of the
variable, you can use a for loop to navigate the array to get the value of
each member of the array:
|
#include <iostream>
using namespace std;
int main()
{
int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int *pNumbers = Number;
int numberOfMembers = sizeof(Number) / sizeof(int);
cout << "List of Numbers";
for(int i = 0; i < NumberOfMembers; i++)
cout << "\nNumber " << i + 1 << ": " << *(pNumbers+i);
return 0;
}
A Pointer as Argument
|
Introduction
|
As we have seen so far, a function can use one or more arguments in
order to carry its assignment. When necessary, a function also declares
its own
variable(s) to get the desired return value.
A variable declared in the body of a function is referred to as a local
variable. Here is an example:
|
#include <iostream> using namespace std; double CalculateNetPrice(double disc); int main() { double finalPrice; double discount = 20; finalPrice = CalculateNetPrice(discount); cout << "\nAfter applying a 20% discount"; cout << "\nFinal Price = " << finalPrice << "\n"; return 0; } double CalculateNetPrice(double d) { double origPrice; cout << "Please enter the original price: "; cin >> origPrice; return origPrice - (origPrice * d / 100); }
Here is an example of running the program:
Please enter the original price: 125.55 After applying a 20% discount Final Price = 100.44 Press any key to continue
Like other variables, a pointer can be passed to a function. When declaring
and when implementing a function that takes a pointer as an argument, use the asterisk for the argument or for each argument.
Here is an example:
|
#include <iostream> using namespace std; double CalculateNetPrice(double *disc); int main() { return 0; } double CalculateNetPrice(double *discount) { double origPrice; cout << "Please enter the original price: "; cin >> origPrice; return origPrice - (origPrice * *discount / 100); }
When calling the function, use the reference(s) to the variable(s). The function
will perform its assignment on the referenced variable(s). After the function
has performed its assignment, the changed value(s) of the argument(s) will be
preserved and given to the calling function. Here is an example:
|
int main()
{
double finalPrice;
double discount = 20;
finalPrice = CalculateNetPrice(&discount);
cout << "\nAfter applying a 20% discount";
cout << "\nFinal Price = " << finalPrice << "\n";
return 0;
}
An example of running the program is:
Please enter the original price: 100 After applying a 20% discount Final Price = 80
- Create a new project named Fire Insurance2
- Create a C++ source file named Main.cpp
- Change the Main.cpp file as follows:
#include <iostream> using namespace std; double GetAnnualPremium(); double GetCoverage(); double GetPolicy(); double CalculatePremium(double Rt, double Cvr, double Plc); int main() { double Rate, Coverage, Policy, Premium; cout << "Fire Insurance - Customer Processing\n"; Rate = GetAnnualPremium(); Coverage = GetCoverage(); Policy = GetPolicy(); Premium = CalculatePremium(Rate, Coverage, Policy); cout << "\n********************************"; cout << "\nFire Insurance - Customer Quote"; cout << "\n________________________________"; cout << "\nAnnual Premium: $" << Rate; cout << "\nCoverage: $" << Coverage; cout << "\nPolicy: $" << Policy; cout << "\nPremium: $" << Premium; cout << "\n********************************\n"; return 0; } double GetAnnualPremium() { double AnlPrem; cout << "Enter the annual premium: $"; cin >> AnlPrem; return AnlPrem; } double GetCoverage() { double Cover; cout << "Enter the coverage: $"; cin >> Cover; return Cover; } double GetPolicy() { double Plc; cout << "Enter the policy amount: $"; cin >> Plc; return Plc; } double CalculatePremium(double Rate, double Cover, double Pol) { double Prem; int Unit; Unit = Pol / Cover; Prem = Rate * Unit; return Prem; }
- Test the program. Here is an example:
Fire Insurance - Customer Processing Enter the annual premium: $0.55 Enter the coverage: $92 Enter the policy amount: $45000 ******************************** Fire Insurance - Customer Quote ________________________________ Annual Premium: $0.55 Coverage: $92 Policy: $45000 Premium: $268.95 ********************************
- Return to your programming environment
- To process arguments as pointers and call the CalculatePremium() function
within main(), change the program as follows:
#include <iostream> using namespace std; double CalculatePremium(double *Rt, double *Cvr, double *Plc); int main() { double Rate, Coverage, Policy, Premium; cout << "Fire Insurance - Customer Processing\n"; cout << "Enter the annual premium: $"; cin >> Rate; cout << "Enter the coverage: $"; cin >> Coverage; cout << "Enter the policy amount: $"; cin >> Policy; Premium = CalculatePremium(&Rate, &Coverage, &Policy); cout << "\n********************************"; cout << "\nFire Insurance - Customer Quote"; cout << "\n________________________________"; cout << "\nAnnual Premium: $" << Rate; cout << "\nCoverage: $" << Coverage; cout << "\nPolicy: $" << Policy; cout << "\nPremium: $" << Premium; cout << "\n********************************\n"; return 0; } double CalculatePremium(double *Rate, double *Cover, double *Pol) { double Prem; int Unit; Unit = *Pol / *Cover; Prem = *Rate * Unit; return Prem; }
- Test the application and return to your programming environment
The Effect of Passing a Pointer as Argument
|
Consider the following program:
#include <iostream> using namespace std; void GetTheOriginalPrice(double OrigPrice); int main() { double OriginalPrice = 0; cout << "First in main() --"; cout << "\nOriginal Price = $" << OriginalPrice << endl; GetTheOriginalPrice(OriginalPrice); cout << "\nBack in main() --"; cout << "\nOriginal Price = $" << OriginalPrice << endl; return 0; } void GetTheOriginalPrice(double OrigPrice) { cout << "\nNow we are in the GetTheOriginalPrice() function"; cout << "\nPlease enter the original price: "; cin >> OrigPrice; cout << "\nIn the GetTheOriginalPrice() function"; cout << "\nOriginal Price = $" << OrigPrice << endl; }
Here is an example of running the program:
First in main() -- Original Price = $0 Now we are in the GetTheOriginalPrice() function Please enter the original price: 100 In the GetTheOriginalPrice() function Original Price = $100 Back in main() -- Original Price = $0
Notice that the value of the OriginalPrice variable is kept intact in the main()
function, as 0, before and after calling the GetTheOriginalPrice() function.
Like a reference, when passing a pointer as argument to a function, the function
that is receiving the argument is in fact accessing the argument's address. Therefore, like
a reference, the called function has the ability to alter the value held by the
pointer. The effect is the same as for the reference: if the called function
modifies the value of the pointer, that value is permanently changed. This is a
feature you can use to your advantage. This effect is illustrated in the
following program:
|
#include <iostream> using namespace std; void GetTheOriginalPrice(double *OrigPrice); int main() { double OriginalPrice = 0; cout << "First in main() --"; cout << "\nOriginal Price = $" << OriginalPrice << endl; GetTheOriginalPrice(&OriginalPrice); cout << "\nBack in main() --"; cout << "\nOriginal Price = $" << OriginalPrice << endl; return 0; } void GetTheOriginalPrice(double *OrigPrice) { cout << "\nNow we are in the GetTheOriginalPrice() function"; cout << "\nPlease enter the original price: "; cin >> *OrigPrice; cout << "\nIn the GetTheOriginalPrice() function"; cout << "\nOriginal Price = $" << *OrigPrice << endl; } |
Here is an example of executing this program:
First in main() -- Original Price = $0 Now we are in the GetTheOriginalPrice() function Please enter the original price: 100 In the GetTheOriginalPrice() function Original Price = $100 Back in main() -- Original Price = $100 Press any key to continue... |
Notice that, this time, after calling the GetTheOriginalPrice() function, the
value of the OriginalPrice variable is permanently changed and the second time
it is accessed in the main() function, it holds a different value than the first
time it was called.
|
|
- To process variables by passing them as reference pointers, change the
Main.cpp file as follows:
#include <iostream> using namespace std; void GetAnnualPremium(double *Prem); void GetCoverage(double *Cvr); void GetPolicy(double *Plc); double CalculatePremium(double *Rt, double *Cvr, double *Plc); int main() { double Rate, Coverage, Policy, Premium; cout << "Fire Insurance - Customer Processing\n"; GetAnnualPremium(&Rate); GetCoverage(&Coverage); GetPolicy(&Policy); Premium = CalculatePremium(&Rate, &Coverage, &Policy); cout << "\n********************************"; cout << "\nFire Insurance - Customer Quote"; cout << "\n________________________________"; cout << "\nAnnual Premium: $" << Rate; cout << "\nCoverage: $" << Coverage; cout << "\nPolicy: $" << Policy; cout << "\nPremium: $" << Premium; cout << "\n********************************\n"; return 0; } void GetAnnualPremium(double *AnlPrem) { cout << "Enter the annual premium: $"; cin >> *AnlPrem; } void GetCoverage(double *Cover) { cout << "Enter the coverage: $"; cin >> *Cover; } void GetPolicy(double *Plc) { cout << "Enter the policy amount: $"; cin >> *Plc; } double CalculatePremium(double *Rate, double *Cover, double *Pol) { double Prem; int Unit; Unit = *Pol / *Cover; Prem = *Rate * Unit; return Prem; }
- Test the application. Here is an example:
Fire Insurance - Customer Processing Enter the annual premium: $0.74 Enter the coverage: $120 Enter the policy amount: $60000 ******************************** Fire Insurance - Customer Quote ________________________________ Annual Premium: $0.74 Coverage: $120 Policy: $60000 Premium: $370 ******************************** Press any key to continue...
- Return to your programming environment
Constant Pointers as Arguments
|
The previous section demonstrates to us that, when passing a
pointer as argument, the effect is the same as passing an argument as reference. This shows that, passing
a pointer as argument gives the called function direct access to the address of
the variable. Besides permanently changing the value of the argument, this
process also speeds up code execution because the called function does not deal
with a copy of the variable but the variable itself. Although there are various good
reasons to pass pointers as arguments, sometimes you may not want the called
function to modify the value held by the variable. In fact you can prevent this.
If a function that receives a pointer as argument is not
supposed to modify the value of the argument, you can pass the argument as a
constant pointer. To do this, type the const keyword on the left side of
the data type of the pointer argument. Here is an example:
|
#include <iostream> using namespace std; double CalculateNetPrice(const double *Disc); int main() { double FinalPrice; double Discount = 20; FinalPrice = CalculateNetPrice(&Discount); cout << "\nAfter applying a 20% discount"; cout << "\nFinal Price = " << FinalPrice << "\n"; return 0; } double CalculateNetPrice(const double *Discount) { double OrigPrice; cout << "Please enter the original price: "; cin >> OrigPrice; return OrigPrice - (OrigPrice * *Discount / 100); }
|
- To pass arguments as constant pointers, change the CalculatePremium()
function as follows:
#include <iostream> using namespace std; void GetAnnualPremium(double *Prem); void GetCoverage(double *Cvr); void GetPolicy(double *Plc); double CalculatePremium( const double *Rt, const double *Cvr, const double *Plc ); int main() { double Rate, Coverage, Policy, Premium; cout << "Fire Insurance - Customer Processing\n"; GetAnnualPremium(&Rate); GetCoverage(&Coverage); GetPolicy(&Policy); Premium = CalculatePremium(&Rate, &Coverage, &Policy); cout << "\n********************************"; cout << "\nFire Insurance - Customer Quote"; cout << "\n________________________________"; cout << "\nAnnual Premium: $" << Rate; cout << "\nCoverage: $" << Coverage; cout << "\nPolicy: $" << Policy; cout << "\nPremium: $" << Premium; cout << "\n********************************\n"; return 0; } void GetAnnualPremium(double *AnlPrem) { cout << "Enter the annual premium: $"; cin >> *AnlPrem; } void GetCoverage(double *Cover) { cout << "Enter the coverage: $"; cin >> *Cover; } void GetPolicy(double *Plc) { cout << "Enter the policy amount: $"; cin >> *Plc; } double CalculatePremium( const double *Rate, const double *Cover, const double *Pol ) { double Prem; int Unit; Unit = *Pol / *Cover; Prem = *Rate * Unit; return Prem; }
- Test the application and return to your programming environment
- Save All
Pointers and Multi-Dimensional Arrays
|
From our study of multidimensional arrays, we know how to
create a two-dimension array as follows:
#include <iostream> using namespace std; int main() { int number[2][6] = { { 31, 28, 31, 30, 31, 30 }, { 31, 31, 30, 31, 30, 31 } }; cout << "List of Numbers"; for(int i = 0; i < 2; i++) for(int j = 0; j < 6; j++) cout << "\nNumber [" << i << "][" << j << "]: " << number[i][j]; return 0; }
In this case, Number is a variable that represents 2 groups
of 6 integers each.
From our first lesson on pointers, we saw that a pointer is
simply created by providing a data type, followed by an asterisk, and followed
by the name of the variable. Here is an example:
int *pNumbers;
We also established that this declaration by itself gives
way to an array after an initialization. This means that we can safely assign
the name of an array to the pointer and the pointer would be initialized.
Since *pNumbers in this example is first of all a variable,
to declare an array of this variable, simply add a dimension and the necessary
square brackets required to declare any array. This can be done as follows:
int *pNumbers[2];
This declaration creates two pointers, and each pointer
points to an array of integers. After this declaration, you can initialize each
pointer as you see fit. In fact, each pointer can point to an array of a
different dimension. This means that one pointer can point to an array of 15
members and another pointer from this declaration can point to an array of 68
members. You have the choice. Since the compiler cannot predict and cannot
decide on the number of members of each array, it is your responsibility to
communicate this. If you want to use the members of an existing array to
initialize the pointer, first specify which pointer you want to initialize,
using its index. To access the first pointer, you would type *(pNumbers+0),
which is the same as *(pNumbers) or *pNumbers. The second pointer can be
accessed with *(pNumbers+1).
Once you have specified which pointer you are interested in,
you can initialize it with the desired dimension of the array. For a
two-dimensional array, you would be initializing the pointer with the
corresponding column, that is, the second index of the array. Here is an example:
*(pNumbers+1) = number[3];
In this case, the second pointer points to the array that is
the second column of the Number variable. Keep in mind that, this time, *pNumbers
is a pointer and not a value. Therefore, to access a member of the array, you
must first specify the desired pointer. Then, using its index, you can get the
corresponding value. Here is an example:
#include <iostream> using namespace std; int main() { int number[2][6] = { { 31, 28, 31, 30, 31, 30 }, { 31, 31, 30, 31, 30, 31 } }; int *pNumbers[2]; *pNumbers = number[0]; (*pNumbers)[0] = number[0][0]; (*pNumbers)[1] = number[0][1]; (*pNumbers)[2] = number[0][2]; (*pNumbers)[3] = number[0][3]; (*pNumbers)[4] = number[0][4]; (*pNumbers)[5] = number[0][5]; *(pNumbers+1) = number[1]; (*(pNumbers+1))[0] = number[1][0]; (*(pNumbers+1))[1] = number[1][1]; (*(pNumbers+1))[2] = number[1][2]; (*(pNumbers+1))[3] = number[1][3]; (*(pNumbers+1))[4] = number[1][4]; (*(pNumbers+1))[5] = number[1][5]; cout << "List of Numbers"; cout << "\n(*pNumbers)[0] = " << (*pNumbers)[0]; cout << "\n(*pNumbers)[1] = " << (*pNumbers)[1]; cout << "\n(*pNumbers)[2] = " << (*pNumbers)[2]; cout << "\n(*pNumbers)[3] = " << (*pNumbers)[3]; cout << "\n(*pNumbers)[4] = " << (*pNumbers)[4]; cout << "\n(*pNumbers)[5] = " << (*pNumbers)[5] << endl; cout << "\n(*(pNumbers+1))[0] = " << (*(pNumbers+1))[0]; cout << "\n(*(pNumbers+1))[1] = " << (*(pNumbers+1))[1]; cout << "\n(*(pNumbers+1))[2] = " << (*(pNumbers+1))[2]; cout << "\n(*(pNumbers+1))[3] = " << (*(pNumbers+1))[3]; cout << "\n(*(pNumbers+1))[4] = " << (*(pNumbers+1))[4]; cout << "\n(*(pNumbers+1))[5] = " << (*(pNumbers+1))[5] << endl; return 0; }
This would produce:
List of Numbers (*pNumbers)[0] = 31 (*pNumbers)[1] = 28 (*pNumbers)[2] = 31 (*pNumbers)[3] = 30 (*pNumbers)[4] = 31 (*pNumbers)[5] = 30 (*(pNumbers+1))[0] = 31 (*(pNumbers+1))[1] = 31 (*(pNumbers+1))[2] = 30 (*(pNumbers+1))[3] = 31 (*(pNumbers+1))[4] = 30 (*(pNumbers+1))[5] = 31 Press any key to continue...
Dynamic Arrays
|
Allocating Memory
|
Based on this relationship between arrays and pointers, you
can use the new operator to dynamically create an array. This has the advantage
of allowing you to allocate the desired amount of space and getting rid of it
once not needed anymore. The syntax of dynamically creating an array of pointers
is:
DataType *ArrayName = new DataType[Dimensions];
To start, type the kind of array you want to create: this is
the DataType.
The ArrayName is a regular name you want to give to
the variable. Since this is a pointer, the array name must be preceded by an
asterisk operator.
Assign the new operator to the array name.
The new operator is followed by the same kind of data
type of the first parameter, DataType.
The the necessary number of members of the array as the Dimension.
This Dimension is included between square brackets, as every array.
Here are examples of dynamic arrays:
double *Distance = new double[12]; unsigned int *pRanges = new unsigned int[120]; float *Prices = new float[44];
After dynamically creating an array, the compiler allocates
the necessary memory space for all the members of the array, based on the data
type and accommodating each. Just like any variable, the memory allocated for
each member of the array contains garbage. It is your responsibility to fill it
up for appropriate values. This can be taken care of by assigning a value to
each member of the array.
Each member of the array can be accessed by using its index
on the name of the array. You have two options. You can apply the index of an
array member on the name of the pointer. Here is an example:
int *pNumbers = new int[12]; pNumbers[0] = 31; pNumbers[1] = 29; pNumbers[2] = 31; pNumbers[3] = 30;
You can also access the address of the desired member, then
assign it a value. Here is an example:
int *pNumbers = new int[12]; *(pNumbers+4) = 31; *(pNumbers+5) = 30; *(pNumbers+6) = 31; *(pNumbers+7) = 31;
In the same way, you can use either method to retrieve the
value of a member of the array:
#include <iostream> using namespace std; int main() { int *pNumbers = new int[12]; pNumbers[0] = 31; pNumbers[1] = 29; pNumbers[2] = 31; pNumbers[3] = 30; *(pNumbers+4) = 31; *(pNumbers+5) = 30; *(pNumbers+6) = 31; *(pNumbers+7) = 31; *(pNumbers+8) = 30; *(pNumbers+9) = 31; pNumbers[10] = 30; pNumbers[11] = 31; cout << "List of numbers"; cout << "\nNumber 1: " << *pNumbers; cout << "\nNumber 2: " << *(pNumbers+1); cout << "\nNumber 3: " << *(pNumbers+2); cout << "\nNumber 4: " << *(pNumbers+3); cout << "\nNumber 5: " << pNumbers[4]; cout << "\nNumber 6: " << pNumbers[5]; cout << "\nNumber 7: " << pNumbers[6]; cout << "\nNumber 8: " << pNumbers[7]; cout << "\nNumber 9: " << *(pNumbers+8); cout << "\nNumber 10: " << *(pNumbers+9); cout << "\nNumber 11: " << pNumbers[10]; cout << "\nNumber 12: " << pNumbers[11]; return 0; }
This would produce:
List of numbers Number 1: 31 Number 2: 29 Number 3: 31 Number 4: 30 Number 5: 31 Number 6: 30 Number 7: 31 Number 8: 31 Number 9: 30 Number 10: 31 Number 11: 30 Number 12: 31 Press any key to continue... |
Disposing of Memory
|
After using a pointer that was pointing to an array, when you do not need it
anymore, you should delete it from memory and reclaim the space it was using.
This is done using the delete operator. The syntax used is:
delete [] VariableName;
The required delete operator is used to let the compiler
know that you want to delete a pointer variable that was pointing to an array.
The delete keyword is followed by empty square
brackets. These brackets allow the compiler to know that you are deleting a
pointer to an array. You must use the square brackets and they
must be empty.
The VariableName must be the name of the pointer.
Here is an example:
#include <iostream>
using namespace std;
int main()
{
int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int *pNumbers = Number;
int numberOfMembers = sizeof(Number) / sizeof(int);
cout << "List of Numbers";
for(int i = 0; i < NumberOfMembers; i++)
cout << "\nNumber " << i + 1 << ": " << *(pNumbers+i);
delete [] pNumbers;
return 0;
}
This operation is usually performed on a dynamically created
array, that is, on a pointer that was used to create an array. The formula is
the same: after using the dynamic array, delete the pointer using the delete
operator. To avoid memory leak, you can also assign NULL to the
name of the array. Here is an example
#include <iostream>
using namespace std;
int main()
{
const int Size = 12;
int *pNumbers = new int[Size];
pNumbers[0] = 31;
pNumbers[1] = 28;
pNumbers[2] = 31;
pNumbers[3] = 30;
*(pNumbers+4) = 31;
*(pNumbers+5) = 30;
*(pNumbers+6) = 31;
*(pNumbers+7) = 31;
*(pNumbers+8) = 30;
*(pNumbers+9) = 31;
pNumbers[10] = 30;
pNumbers[11] = 31;
cout << "List of numbers";
for(int i = 0; i < Size; i++)
cout << "\nNumber " << i + 1 << ": " << *(pNumbers+i);
delete [] pNumbers;
pNumbers = NULL;
return 0;
}
Dynamic Multi-Dimensional Arrays
|
As done with the two-dimension array, to declare a pointer
to a multi-dimensional array, type a name for the variable, preceded by the
pointers type and the asterisk operator. To make it an array, make sure you
specify its dimension. Here is an example:
int *pNumbers[2];
Since this creates two pointers, and each pointer is an
array, you must initialize each pointer. This can be done using the new operator
and following the same syntax used previously. For example, to specify the first
pointer as an array of 8 members, you would type:
*pNumbers = new int[8];
To provide a value to a member of the array, provide the
address of its pointer and specify its index. After using a pointer, you should
make sure you delete it and reclaim the memory it was using. This can be
summarized as follows:
#include <iostream> using namespace std; int main() { int *pNumbers[2]; *pNumbers = new int[0]; (*pNumbers)[0] = 31; (*pNumbers)[1] = 29; (*pNumbers)[2] = 31; (*pNumbers)[3] = 30; (*pNumbers)[4] = 31; (*pNumbers)[5] = 30; *(pNumbers+1) = new int[1]; (*(pNumbers+1))[0] = 31; (*(pNumbers+1))[1] = 31; (*(pNumbers+1))[2] = 30; (*(pNumbers+1))[3] = 31; (*(pNumbers+1))[4] = 30; (*(pNumbers+1))[5] = 31; cout << "List of Numbers"; cout << "\n(*pNumbers)[0] = " << (*pNumbers)[0]; cout << "\n(*pNumbers)[1] = " << (*pNumbers)[1]; cout << "\n(*pNumbers)[2] = " << (*pNumbers)[2]; cout << "\n(*pNumbers)[3] = " << (*pNumbers)[3]; cout << "\n(*pNumbers)[4] = " << (*pNumbers)[4]; cout << "\n(*pNumbers)[5] = " << (*pNumbers)[5] << endl; cout << "\n(*(pNumbers+1))[0] = " << (*(pNumbers+1))[0]; cout << "\n(*(pNumbers+1))[1] = " << (*(pNumbers+1))[1]; cout << "\n(*(pNumbers+1))[2] = " << (*(pNumbers+1))[2]; cout << "\n(*(pNumbers+1))[3] = " << (*(pNumbers+1))[3]; cout << "\n(*(pNumbers+1))[4] = " << (*(pNumbers+1))[4]; cout << "\n(*(pNumbers+1))[5] = " << (*(pNumbers+1))[5] << endl; delete [] *pNumbers; delete [] *(pNumbers+1); return 0; }
This would produce;
List of Numbers (*pNumbers)[0] = 31 (*pNumbers)[1] = 29 (*pNumbers)[2] = 31 (*pNumbers)[3] = 30 (*pNumbers)[4] = 31 (*pNumbers)[5] = 30 (*(pNumbers+1))[0] = 31 (*(pNumbers+1))[1] = 31 (*(pNumbers+1))[2] = 30 (*(pNumbers+1))[3] = 31 (*(pNumbers+1))[4] = 30 (*(pNumbers+1))[5] = 31 Press any key to continue...
Pointers and Arrays With Functions
|
Single Dimensional Arrays and Functions
|
When we studied arrays and functions, we saw that, to pass
an array as argument to a function, you can type the name of the argument
followed by parentheses. If you want to process the members of the array, you
should also pass another argument that holds the number of members of the array.
Here is an example:
int SumOfNumbers(int Nbr[], int Size);
When calling such a function, the name of the argument is
sufficient to the compiler:
#include <iostream>
using namespace std;
int SumOfNumbers(int Nbr[], int Size)
{
int Sum = 0;
for(int i = 0; i < Size; i++)
Sum += Nbr[i];
return Sum;
}
int main()
{
int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int numberOfMembers = sizeof(Number) / sizeof(int);
int Value = SumOfNumbers(number, numberOfMembers);
cout << "Sum of numbers: " << Value;
return 0;
}
This would produce:
Sum of numbers: 365
When calling the function, the name of the array allows the
compiler to pass the whole array because that name is in fact a pointer to the
variable. Based on this, instead of passing an array as argument, you can instead
use a pointer. We have established that, once a pointer has been initialized as
holding the address of an array, the name of the array and the name of the pointer point
to the same address. This means that you can also use the name of the pointer
when calling such a function. Remember that the name of the pointer preceded by an
asterisk is a value; therefore, you should not use it as argument when calling
the function.
Based on the relationship we have studied so far between
pointers and arrays, the above program can also be written as follows:
#include <iostream> using namespace std; int SumOfNumbers(int *nbr, int size) { int sum = 0; for(int i = 0; i < size; i++) sum += nbr[i]; return Sum; } int main() { int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = number; int numberOfMembers = sizeof(number) / sizeof(int); int Value = SumOfNumbers(pNumbers, numberOfMembers); cout << "Sum of numbers: " << Value; return 0; }
This would produce the same result.
|
Multi-Dimensional Arrays and Functions
|
To declare a function that takes a multi-dimensional array as argument, you can
type the array name followed by an empty pair of square brackets, followed by a
second pair of square brackets that contain the number of columns. If you are
using a pointer as argument, for example a variable that points to a
two-dimensional array, provide the type of variable followed by an asterisk that
indicates that the argument is a pointer, and followed by a pair of square
brackets. The square brackets can be empty or contain the number of columns.
Such a function can be declared as follows:
void DisplayNumbers(int *nbr[]);
Before calling such a function, after appropriately initializing the pointer,
provide only the name of the pointer. Here is an example:
#include <iostream> using namespace std; void DisplayNumbers(int *Nbr[]); int main() { int number[2][6] = { { 31, 28, 31, 30, 31, 30 }, { 31, 31, 30, 31, 30, 31 } }; int *pNumbers[2]; *pNumbers = number[0]; (*pNumbers)[0] = number[0][0]; (*pNumbers)[1] = number[0][1]; (*pNumbers)[2] = number[0][2]; (*pNumbers)[3] = number[0][3]; (*pNumbers)[4] = number[0][4]; (*pNumbers)[5] = number[0][5]; *(pNumbers+1) = number[1]; (*(pNumbers+1))[0] = number[1][0]; (*(pNumbers+1))[1] = number[1][1]; (*(pNumbers+1))[2] = number[1][2]; (*(pNumbers+1))[3] = number[1][3]; (*(pNumbers+1))[4] = number[1][4]; (*(pNumbers+1))[5] = number[1][5]; cout << "List of Numbers"; DisplayNumbers(pNumbers); return 0; } void DisplayNumbers(int *nbr[]) { cout << "\n(*pNumbers)[0] = " << (*nbr)[0]; cout << "\n(*pNumbers)[1] = " << (*nbr)[1]; cout << "\n(*pNumbers)[2] = " << (*nbr)[2]; cout << "\n(*pNumbers)[3] = " << (*nbr)[3]; cout << "\n(*pNumbers)[4] = " << (*nbr)[4]; cout << "\n(*pNumbers)[5] = " << (*nbr)[5] << endl; cout << "\n(*(pNumbers+1))[0] = " << (*(nbr+1))[0]; cout << "\n(*(pNumbers+1))[1] = " << (*(nbr+1))[1]; cout << "\n(*(pNumbers+1))[2] = " << (*(nbr+1))[2]; cout << "\n(*(pNumbers+1))[3] = " << (*(nbr+1))[3]; cout << "\n(*(pNumbers+1))[4] = " << (*(nbr+1))[4]; cout << "\n(*(pNumbers+1))[5] = " << (*(nbr+1))[5] << endl; }
If you want to process the argument in the function where it is passed as
argument and if you would not know the dimension of the array in advance, you
can pass two additional arguments that represent the rows and columns of the
array. Here is an example:
#include <iostream> using namespace std; void DisplayNumbers(int *Nbr[], int r, int c); int main() { int number[2][6] = { { 31, 28, 31, 30, 31, 30 }, { 31, 31, 30, 31, 30, 31 } }; int *pNumbers[2]; *pNumbers = number[0]; for(int i = 0; i < 6; i++) (*pNumbers)[i] = number[0][i]; *(pNumbers+1) = number[1]; for(int i = 0; i < 6; i++) (*(pNumbers+1))[i] = number[1][i]; cout << "List of Numbers"; DisplayNumbers(pNumbers, 2, 6); return 0; } void DisplayNumbers(int *nbr[], int rows, int columns) { for(int i = 0; i < rows; i++) for(int j = 0; j < columns; j++) cout << "\nNumber[" << i << "][" << j << "]: " << (*(nbr+i))[j]; } |
Here is an example of executing this program:
List of Numbers Number[0][0]: 31 Number[0][1]: 28 Number[0][2]: 31 Number[0][3]: 30 Number[0][4]: 31 Number[0][5]: 30 Number[1][0]: 31 Number[1][1]: 31 Number[1][2]: 30 Number[1][3]: 31 Number[1][4]: 30 Number[1][5]: 31
No comments:
Post a Comment