Sie sind auf Seite 1von 78

Introduction to Arrays

http://www.functionx.com/cpp/Lesson12.htm

Arrays Fundamentals
Introduction

An array of airplanes

An array of bugs

An array of cards

An array of characters

When you look at the stuff on each group above, you realize that the items on each picture share a lot of characteristics, though each one still maintains specific features that set it apart from the others. Everyone of the items on the first picture is an airplane; if you decide to be specific, then you may state that the first airplane of the group is bright green while the second is black; the first and the fourth airplanes don't have helices although all the others do. On the second picture (from left to right), all of these items are bugs; they don't seem to look alike, but everyone of them is still a bug. If you play cards sometimes (Solitaire or FreeCell), then you are familiar with the third picture. Everyone of the items on the third picture is a card, same size, same white background, though they display different card values, different character colors (and they would have different effects depending on how your game is going). Whenever you are typing, you are aligning arrays of characters, characters as those of the last picture. This shows that a word or a sentence is actually a group or letters. An array is a group of items that can be identified as similar because they are of the same nature. Arrays come in two flavors: one dimensional and multi-dimensional arrays. Everyone of the pictures above represents a single dimensional array.

Declaring an Array
Just like any variable you are already familiar with, an array has to be declared before being used. Yet the difference this time is that you need to tell the compiler what kind of array you are defining, an array of books? An array of students? An array of billiard balls? An arrays of clothes? This is because, once more, the compiler wants to know how much space your array is going to occupy in the computer memory. This is because when you declare an array of items, the compiler puts each one of the items in an appropriate location. Like any other variable, the syntax of declaring an array is:
DataType ArrayName[dimension\order]

The array is first identified by its kind, which could be a char, an int, a float, etc; followed by its name that follows the C++ naming rules. The name is then followed by square brackets that specify the dimension of the array or its size. Here are examples of declaring arrays:
int age[12]; float grade[100]; double angle[360];

int Age[12]; declares a group or array of 12 values, each one being an integer. float Grade[100]; declares an array of 100 floating-point values. double Angle[360]; declares an array of double-precision numbers. There are 360 of these items in the group.

Initializing an Array
Just like any variable can be initialized, an array also can be initialized. To accomplish this, for a one-dimensional array, the syntax used is:
DataType ArrayName[dimension] = { element1, element2, , elementn};

Therefore, you can start with the data type to specify the kind of array you are declaring. This is followed by the array name, and the square brackets. After specifying the dimension or not, and after the closing square bracket, type the assignment operator. The elements, also called items, that compose the array are included between an opening curly bracket '{' and a closing curly bracket '}'. Each item is separate from the next by a comma operator. As a normal C/C++ initialization, you end it with a semi-colon. Here are examples of declaring an initializing arrays: If you have decided to initialize the array while you are declaring it, you can omit the dimension. Therefore, these arrays can be declared as follows:

int number[12] = {18, 42, 25, 12, 34, 15, 63, 72, 92, 26, 26, 12}; double distance[5] = {44.14, 720.52, 96.08, 468.78, 6.28};

int number[] = {18, 42, 25, 12, 34, 15, 63, 72, 92, 26, 26, 12}; double distance[] = {44.14, 720.52, 96.08, 468.78, 6.28};

Processing the Elements of an Array

After initializing an array, its elements are counted from left to right. Each element of the array, also called a member of the array, has a specific and constant position. The position of an item is also called its index. The first member of the array, the most left, has an index of 0. The second member of the array has an index of 1. Since each array has a number of items which can be specified as n, the last member of the array has an index of n-1 Based on this system of indexing, to locate a member of an array, use its index in the group. Imagine you declare and initialize an array as follows:
double distance[] = {44.14, 720.52, 96.08, 468.78, 6.28};

To locate the value of the 3rd member of the array, you would type distance[2]. In the same way, the 1st member of the array can be located with distance[0]. Once you can locate a member of the array, you can display its value using cout. Here is an example:

#include <iostream> using namespace std; int main() { double distance[] = {44.14, 720.52, 96.08, 468.78, 6.28}; cout << "2nd member = " << distance[1] << endl; cout << "5th member = " << distance[4] << endl; return 0; }

This would produce:


2nd member = 720.52 5th member = 6.28

Using this approach, each member of the array can have example:
#include <iostream> using namespace std; int main() { double distance[] = {44.14, 720.52, 96.08, 468.78, 6.28}; cout << "Distance 1: " << distance[0] << endl; cout << "Distance 2: " << distance[1] << endl;

its value accessed. Here is an

cout << "Distance 3: " << distance[2] << endl; cout << "Distance 4: " << distance[3] << endl; cout << "Distance 5: " << distance[4] << endl; return 0; }

This would produce:


Distance Distance Distance Distance Distance 1: 2: 3: 4: 5: 44.14 720.52 96.08 468.78 6.28

The Size of an Array


When declaring an array, we saw that you must specify the number of items that the array is made of. Here is an example:
float averagePrice[45];

Depending on how you want to deal with your array, you may sometimes need to increase or decrease its dimension. To do this, you would need to locate the declaration of the array and change its dimension. If the program is long and the array is declared in some unusual place, this could take some time. The alternative is to define a constant prior to declaring the array and use that constant to hold the dimension of the array. Here is an example:
#include <iostream> using namespace std; int main() { const int numberOfItems = 5; double distance[numberOfItems] = {44.14, 720.52, 96.08, 468.78, 6.28}; cout cout cout cout cout } << << << << << "Distance "Distance "Distance "Distance "Distance 1: 2: 3: 4: 5: " " " " " << << << << << distance[0] distance[1] distance[2] distance[3] distance[4] << << << << << endl; endl; endl; endl; endl;

return 0;

You can use such a constant in a for loop to scan the array and access each of its members. Here is an example:
#include <iostream> using namespace std; int main() { const int numberOfItems = 5; double distance[numberOfItems] = {44.14, 720.52, 96.08, 468.78, 6.28}; cout << "Members of the array\n"; for(int i = 0; i < numberOfItems; ++i) cout << "Distance " << i + 1 << ": " << distance[i] << endl; return 0; }

In both cases, this would produce:


Members of the array Distance 1: 44.14 Distance 2: 720.52 Distance 3: 96.08 Distance 4: 468.78 Distance 5: 6.28

We knew the dimensions of the arrays we have used so far, because we could count the number of members of the array. Imagine you declare a large array, possibly made of 100 or

300 members, you wouldn't start counting the number of members. C/C++ provides the sizeofoperator that can be used to get the dimension of an array. The syntax you would use is:
sizeof(ArrayName) / sizeof(DataType)

Imagine you declare an array as follows:


int number[] = {18, 42, 25, 12, 34, 15, 63, 72, 92, 26, 26, 12, 127, 4762, 823, 236, 84, 5};

Instead of counting the number of members of this array (it makes me dizzy when I try), you can use the sizeof operator as follows:
int NumberOfItemsOfTheArray = sizeof(Number)/sizeof(int);

One of the advantages of the sizeof operator used to get the number of members of the array is that it can be used on a for loop to scan an array, either to locate the members or to look for a value in the array. Here is an example of using this concept:
#include <iostream> using namespace std; int main() { double distance[] = {44.14, 720.52, 96.08, 468.78, 6.28}; // Using the sizeof operator to get the dimension of the array int index = sizeof(distance) / sizeof(double); cout << "Array members and their values\n"; // Using a for loop to scan an array for(int i = 0; i < index; ++i) cout << "Distance : " << i + 1 << distance[i] << endl; return 0; }

This would produce:


Array members and their values Distance : 144.14 Distance : 2720.52 Distance : 396.08 Distance : 4468.78 Distance : 56.28

Filling Up an Array

When you declare an array without initializing it, we have mentioned that the compiler reserves an amount of memory space for the members of the array. But that is only what the compiler does. Each part of such reserved space is filled with garbage. Therefore, you must make sure that you know the value held by a member of the array before making any attempt to process the value held by that member of the array. Consider the following example:
#include <iostream> using namespace std; int main() { const int numberOfItems = 5; double distance[numberOfItems]; cout cout cout cout cout } << << << << << "Distance "Distance "Distance "Distance "Distance 1: 2: 3: 4: 5: " " " " " << << << << << distance[0] distance[1] distance[2] distance[3] distance[4] << << << << << endl; endl; endl; endl; endl;

return 0;

This would produce:


Distance Distance Distance Distance 1: 2: 3: 4: -9.25596e+061 -9.25596e+061 -9.25596e+061 -9.25596e+061

Distance 5: -9.25596e+061

As you can see, the members of the array in the beginning don't have any recognizable value. There are two solutions to this problem. You can either initialize the array or request the values of the members of the array from the user. So far, when we used an array, we made sure to provide the exact number of members we needed for the array. We also saw that we could declare and initialize an array without specifying its dimension. The advantage of not specifying the dimension of the array is that we trust the compiler to find out the number of elements of the array. If you decide to specify the dimension of the array and initialize it, make sure you specify the elements less than or equal to the number you specified. Here is an example:
#include <iostream> using namespace std; int main() { const int numberOfItems = 5; double distance[numberOfItems] = {44.14, 720.52, 96.08}; cout cout cout cout cout } << << << << << "Distance "Distance "Distance "Distance "Distance 1: 2: 3: 4: 5: " " " " " << << << << << distance[0] distance[1] distance[2] distance[3] distance[4] << << << << << endl; endl; endl; endl; endl;

return 0;

This would produce:


Distance Distance Distance Distance Distance 1: 2: 3: 4: 5: 44.14 720.52 96.08 0 0

If you provide more members than the number of elements you specified, the compiler would provide garbage values to the extra members. Here is an example:
#include <iostream> using namespace std; int main() { const int NumberOfItems = 5; double distance[NumberOfItems] = {44.14, 720.52, 96.08, 468.78, 6.28}; cout cout cout cout cout cout cout cout } << << << << << << << << "Distance "Distance "Distance "Distance "Distance "Distance "Distance "Distance 1: 2: 3: 4: 5: 6: 7: 8: " " " " " " " " << << << << << << << << distance[0] distance[1] distance[2] distance[3] distance[4] distance[5] distance[6] distance[7] << << << << << << << << endl; endl; endl; endl; endl; endl; endl; endl;

return 0;

This would produce:


Distance 1: 44.14 Distance 2: 720.52 Distance 3: 96.08 Distance 4: 468.78 Distance 5: 6.28 Distance 6: 2.64214e-308 Distance 7: 2.12414e-314 Distance 8: 1.00532e-307

Depending on the compiler you are using, you would also receive a (strong) warning.

Streaming Array Members


We have already seen how to define an array, how to locate the elements of an array, and how to display the values of these elements (displaying the value of a member of an array is one aspect of streaming). The arrays we have seen so far had their dimensions and their elements defined by the programmer. Many times you will have to get these elements from the user. When you need to get an array from the user, first decide on what kind of array it is. Next, try to think of the maximum number of members you will need for the array. When you define an array and specify its dimension, the compiler will reserve the number of cells in memory that can accommodate your array. Here is an example:
int Page[5];

Each member of the array can be located using its index, as we have seen so far. In the same way, you can request the value of any member of the array using its index. In the following example, we declare an array of 5 integers and then we request the values of the 1 st and the 4th members:
#include <iostream> using namespace std; int main() { const int counter = 5; int page[counter]; cout << "Enter the number of pages of your books\n"; cout << "Book 1: "; cin >> page[0]; cout << "Book 4: "; cin >> page[3]; cout << "\nSummary of books"; cout << "\nBook 1: " << page[0] << " pages"; cout << "\nBook 4: " << page[3] << " pages\n"; return 0; }

Here is an example of running the program:

Enter the number of pages of your books Book 1: 842 Book 4: 1204 Summary of books Book 1: 842 pages Book 4: 1204 pages

Operations on Arrays
Each member of an array is a pseudo-variable and can be processed as such. This means that you can add the values of two members of the array(Number[2]+Number[0]), you can subtract the value of one of the members from another member(member[1]-Number[4]). In the same way, you can perform multiplication, division, or remainder operations on members of an array. One of the regular operations performed on an array consists of adding the values of the members to produce a sum. Here is an example:
#include <iostream> using namespace std; int main() { // We know that we need a constant number of elements const int max = 10; int number[max];

// We will calculate their sum int sum = 0; cout << "Please type 10 integers.\n"; for( int i = 0; i < max; i++ ) { cout << "Number " << i + 1 << ": "; cin >> number[i]; sum += number[i]; } cout << "\n\nThe sum of these numbers is " << Sum << "\n\n"; return 0; }

This would produce:


Please type 10 integers. Number 1: 120 Number 2: 42 Number 3: 75 Number 4: 38 Number 5: 904 Number 6: 6 Number 7: 26 Number 8: 55 Number 9: 92 Number 10: 20 The sum of these numbers is 1378 Another type of operation regularly performed on an array consists of looking for a value held by one of its members. For example, you can try to know if one of the members holds a particular value you are looking for. Here is an example:
#include <iostream> using namespace std; int main() { // Declare the members of the array int numbers[] = {8, 25, 36, 44, 52, 60, 75, 89}; int find; int i, m = 8; cout << "Enter a number to search: "; cin >> find; for (i = 0; (i < m) && (Numbers[i] != Find); ++i) continue; // Find whether the number typed is a member of the array if (i == m) cout << find << " is not in the list" << endl; else cout << find << " is the " << i + 1 << "th element in the list" << endl; return 0; }

This would produce:


Enter a number to search: 44 44 is the 4th element in the list

One of the most regular operations performed consists of comparing the values of different members to get the lowest value of the members. Here is an example:
// Example of finding the minimum member of an array #include <iostream> using namespace std; int main() { // The members of the array int numbers[] = {8, 25, 36, 44, 52, 60, 75, 89}; int minimum = numbers[0]; int a = 8; // Compare the members for (int i = 1; i < a; ++i) { if (numbers[i] < minimum) minimum = numbers[i]; } // Announce the result cout << "The lowest member value of the array is " << minimum << "." << endl; return 0; }

This would produce:


The lowest member value of the array is 8.

You can use this same approach to get the maximum value of the members of an array. Here is an example:
// Example of finding the maximum member of an array #include <iostream> using namespace std; int main() { // The members of the array int numbers[] = {8, 25, 36, 44, 52, 60, 75, 89}; int maximum = numbers[0]; int a = 8; // Compare the members for (int i = 1; i < a; ++i) { if (numbers[i] > maximum) maximum = numbers[i]; } // Announce the result cout << "The highest member value of the array is " << maximum << "." << endl; return 0; }

Arrays and Functions


An array can be passed to a function as argument. An array can also be returned by a function. To declare and define that a function takes an array as argument, declare the function as you would do for any regular function and, in its parentheses, specify that the argument is an array. Here is an example:
#include <iostream> using namespace std; void DisplayTheArray(double member[5]);

int main() { const int numberOfItems = 5; double distance[numberOfItems] = {44.14, 720.52, 96.08, 468.78, 6.28}; return 0; } void DisplayTheArray(double member[5]) { for(int i = 0; i < 5; ++i) cout << "\nDistance " << i + 1 << ": " << member[i]; cout << endl; }

You don't have to specify the dimension of the array. This means that you can leave the square brackets empty:
#include <iostream> using namespace std; void DisplayTheArray(double member[]); int main() { const int NumberOfItems = 5; double distance[NumberOfItems] = {44.14, 720.52, 96.08, 468.78, 6.28}; return 0; } void DisplayTheArray(double member[]) { for(int i = 0; i < 5; ++i) cout << "\nDistance " << i + 1 << ": " << member[i]; cout << endl; }

We have already seen that when you declare an array, the compiler reserves an amount of memory space for the members of the array. To locate these members, the compiler aligns them in a consecutive manner. For example (hypothetically), if a member is located at 1804 Lockwood drive, the next member would be located at 1805 Lockwood Drive. This allows the compiler not only to know where the members of a particular array are stored, but also in what block (like the block houses of a city) the array starts. This means that, when you ask the compiler to locate a member of an array, the compiler starts where the array starts and moves on subsequently until it finds the member you specified. If the compiler reaches the end of the block but doesn't find the member you specified, it stops, instead of looking for it all over the computer memory. Based on this, when you call a function that has an array as argument, the compiler only needs the name of the array to process it. Therefore, the above function can be called as follows:
#include <iostream> using namespace std; void DisplayTheArray(double member[]) { for(int i = 0; i < 5; ++i) cout << "\nDistance " << i + 1 << ": " << member[i]; cout << endl; } int main() { const int numberOfItems = 5; double distance[numberOfItems] = {44.14, 720.52, 96.08, 468.78, 6.28};

cout << "Members of the array"; DisplayTheArray(distance); return 0; }

This would produce:


Members of the array Distance 1: 44.14 Distance 2: 720.52 Distance 3: 96.08 Distance 4: 468.78 Distance 5: 6.28

The good scenario we have used so far is that we know the number of members of our array and we can directly use it in the function that is passed the argument. Imagine that we want the function to know how many members the array has and we want to let the function know while we are calling it, after all, in some circumstances, we will not always know how many members we want the function to process. This should easily be done as follows:
#include <iostream> using namespace std; void DisplayTheArray(double member[]) { for(int i = 0; i < 5; ++i) cout << "\nDistance " << i + 1 << ": " << member[i]; cout << endl; } int main() { const int NumberOfItems = 5; double distance[NumberOfItems] = {44.14, 720.52, 96.08, 468.78, 6.28}; cout << "Members of the array"; DisplayTheArray(distance[3]); return 0; }

Unfortunately, this program will not compile. Remember, we saw that the compiler wants only the name of the array, because the name by itself represents the whole array. distance[3] is a specific value of a member of the array, it is not a group of values. In other words, distance[3] is the same as 468.78. It is as if we want to pass 468.78 as the value to be treated and not as a subsequent group of values, because that is what an array is. Therefore, the compiler complains that you are passing a value after you have specifically stated that the argument was a group of values and not a single value. When you declare and define a function that takes an array as argument, if you plan to process the array, for example, if you want the calling function to control the number of elements to be processed, you should/must pass another argument that will allow the function to know how many members of the array would be considered. Such a function can be declared as follows:
#include <iostream> using namespace std; void DisplayTheArray(double mbr[], int count); int main() { double distance[] = {44.14, 720.52, 96.08, 468.78, 6.28, 68.04, 364.55, 6234.12}; // Processing 5 members of the array cout << "Members of the array"; DisplayTheArray(distance, 5);

// Processing all members of the array int sizeOfArray = sizeof(Distance)/sizeof(double); cout << "\nMembers of the array"; DisplayTheArray(distance, sizeOfArray); return 0; } void DisplayTheArray(double member[], int counter) { for(int i = 0; i < counter; ++i) cout << "\nDistance " << i + 1 << ": " << member[i]; cout << endl; }

This would produce:


Members of the array Distance 1: 44.14 Distance 2: 720.52 Distance 3: 96.08 Distance 4: 468.78 Distance 5: 6.28 Members of the array Distance 1: 44.14 Distance 2: 720.52 Distance 3: 96.08 Distance 4: 468.78 Distance 5: 6.28 Distance 6: 68.04 Distance 7: 364.55 Distance 8: 6234.12

Using this same concept of passing accompanying arguments, you can control how the called function would process the array. For example, you can specify the starting and end point to the processing of the array. Here is an example:
#include <iostream> using namespace std; // This function process an array but starts and ends at specific positions void DisplayTheArray(double mbr[], int Start, int End); int main() { double distance[] = {44.14, 720.52, 96.08, 468.78, 6.28, 68.04, 364.55, 6234.12}; // Scan the array from the 3rd to the 7th member cout << "Members of the array"; DisplayTheArray(distance, 2, 6); return 0; } void DisplayTheArray(double member[], int start, int ending) { for(int i = start; i < ending; ++i) cout << "\nDistance " << i + 1 << ": " << member[i]; cout << endl; }

This would produce:


Members of the array Distance 3: 96.08 Distance 4: 468.78 Distance 5: 6.28 Distance 6: 68.04

When declaring a function that takes an array argument, as we learned with other arguments, you don't have to provide a name to the argument. Simply typing the square brackets on the right side of the data type in the parentheses is enough. The name of the argument is only necessary when defining the function. Therefore, the above function can be declared as follows:
#include <iostream> using namespace std; // This function process an array but starts and ends at specific positions void DisplayTheArray(double[], int, int); int main() { double distance[] = {44.14, 720.52, 96.08, 468.78, 6.28, 68.04, 364.55, 6234.12}; // Scan the array from the 3rd to the 7th member cout << "Members of the array"; DisplayTheArray(distance, 2, 6); return 0; } void DisplayTheArray(double member[], int Start, int Ending) { for(int i = Start; i < Ending; ++i) cout << "\nDistance " << i + 1 << ": " << member[i]; cout << endl; }

Two-Dimensional Arrays
Introduction

A 2-dimensional array is an array of arrays. In other words, it is an array where each member of the array is also an array. Consider the following table Country\Data United States Cameroon Map Flag Area (sq km) 9,629,091 475,440 Population 272,639,608 15,456,092

Guatemala

108,890

12,335,580

Italy

301,230

56,735,130

Oman

212,460

2,446,645

Declaring and Initializing a 2-Dimensional Array


This two-dimensional array is made of rows and columns . Each column represents one category of data that everyone of the rows shares with the other rows. As different as each map looks, it still remains a map; each country on the table is known for its map, its flag, its area, and its population, though remaining different from the others. To see another twodimensional array, look at a calendar that displays a month with its week days. Like the above table, a 2-dimensional array is made rows and columns. To declare it,

use

doublepair of a opening and closing square brackets. Here is an example:

int numberOfStudentsPerClass[12][50];

This declaration creates a first group of 12 elements; it could be an array of 12 classes. Each element of the array contains 50 elements. In other words, each of the 12 members of the group is an array of 50 items. Simply stated, this declarations creates 12 classes and each class contains 50 students. Before using the members of an arrays, you should/must make sure you know the values that its members hold. As done with one-dimensional arrays, there are two ways you can solve this problem: you can initialize the array or you can get its values by another means. You can initialize an array the same way you would proceed the a one-dimensional array: simply provide a list of values in the curly brackets. A multidimensional array is represented as an algebraic matrix as MxN. This means that the array is made of M rows and N columns. For example, a 5x8 matrix is made of 5 rows and 8 columns. To know the actual number of members of a multidimensional array, you can multiply the number of rows by the number of columns. Therefore a 2x16 array contains 2*16=32 members. Based on this, when initializing a 2-dimensional array, make sure you provide a number of values that is less than or equal to the number of members. Here is an example:
double distance[2][4] = {44.14, 720.52, 96.08, 468.78, 6.28, 68.04, 364.55, 6234.12};

To locate a member of the array, this time, each must be identified by its double index. The first member is indexed at [0][0]. The second is at [0][1]. For a 2x4 array as this one, the 5th member is at [1][0]. You can use this same approach to display the values of the members of the array. Here is an example:
#include <iostream> using namespace std; int main() { // A 2-Dimensional array double distance[2][4] = {44.14, 720.52, 96.08, 468.78, 6.28, 68.04, 364.55, 6234.12}; // Scan the array from the 3rd to the 7th member cout << "Members of the array"; cout << "\nDistance [0][0]" << ": " << distance[0][0]; cout << "\nDistance [0][1]" << ": " << distance[0][1]; cout << "\nDistance [0][2]" << ": " << distance[0][2]; cout << "\nDistance [0][3]" << ": " << distance[0][3]; cout << "\nDistance [1][0]" << ": " << distance[1][0]; cout << "\nDistance [1][1]" << ": " << distance[1][1]; cout << "\nDistance [1][2]" << ": " << distance[1][2]; cout << "\nDistance [1][3]" << ": " << distance[1][3]; cout << endl; return 0; }

This would produce:


Members of the array Distance [0][0]: 44.14 Distance [0][1]: 720.52 Distance [0][2]: 96.08 Distance [0][3]: 468.78 Distance [1][0]: 6.28 Distance [1][1]: 68.04 Distance [1][2]: 364.55 Distance [1][3]: 6234.12

To make the above array a little easier to read when initializing it, you can type the values of each row on its own line. For example, the above array can be initialized as follows:
double distance[2][4] = { 44.14, 720.52, 96.08, 468.78, 6.28, 68.04, 364.55, 6234.12 };

C++ also allows you to include each row in its own pair of curly brackets. You must separate each row from the next with a comma. Once again, this makes code easier to read. Here is an

example:
double distance[2][4] = { { 44.14, 720.52, 96.08, 468.78 }, { 6.28, 68.04, 364.55, 6234.12 } };

Processing a 2-Dimensional Array


To scan a 2-dimensional array, you should know how many columns the array contains. You can use two for loops to navigate the array. Here is an example:
#include <iostream> using namespace std; int main() { // A 2-Dimensional array double distance[][4] = { { 44.14, 720.52, 96.08, 468.78 }, { 6.28, 68.04, 364.55, 6234.12 } }; // Scan the array from the 3rd to the 7th member cout << "Members of the array"; for(int i = 0; i < 2; ++i) for(int j = 0; j < 4; ++j) cout << "\nDistance [" << i << "][" << j << "]: " << distance[i][j]; cout << endl; return 0; }

This would produce the same result as previously.

Introduction to Pointers
Pointers Fundamentals
Introduction
When writing a program, you declare the necessary variables that you will need in order to accomplish your work. When declaring variables, you are simply asking the computer to reserve a set amount of space in its memory for a particular object you want to use. When you declare a variable, the computer reserves an amount of space for that variable, and uses the variable's name to refer to that memory space. This will allow you to store something, namely the value of that variable, in that space. Indeed, the computer refers to that space using an address. Therefore, everything you declare has an address, just like the address of your house. You can find out what address a particular variable is using.

A Review of References and Functions


Here are a few things you know already about writing a program: To use a variable, you declare it first to tell the compiler what kind of variable you are planning to use and what its name is . Once you declare a variable, the compiler reserves and assigns it a portion of space in memory and locates it there so that whenever you need that variable, you just call it and then use it. To use a function, you have to define it, tell the compiler what the function is supposed to do,

and whether the function is supposed to give back a result or not, after it has performed its assignment. To see a variable's address, you can use the & operator followed by the name of the variable. For example, after declaring an integer as
int numberOfStudents;

you can find the address where the NumberOfStudents variable is located by using:
cout << &numberOfStudents;

This program would give you the address of the declared variable:
#include <iostream> using namespace std;

int main() { int value;

cout << "Value lives at " << &value;

cout << "\n\n"; return 0; }

After executing the program, you could get:


Value lives at: 0x0065FDF4

Using Pointers
Why Use Pointers?
Every time you declare a variable, the compiler puts it somewhere, which you can now refer to as an address. Once you know that address, you can use it. Like a reference, when you pass an argument to a function, the argument is passed using its address. This allows the calling function to dig into the address of the variable (the argument) and use the value directly. This transaction, like that of passing an argument by reference, allows the calling function to alter the real value of the argument. Using this ability, a pointer can allow you to return many values from a function; as opposed to a regular argument passing where the data, although changed inside of the calling function, will regain its previous value once the calling function is exited. Therefore, passing arguments as pointers allows a function to return many values, even if a function is declared as void. When you declare an array, you must specify the dimension of the array. That's already a problem: what if you don't know and don't want to know the dimension of the array? Pointers provide an ability that regular arrays do not have. Since pointers have a different and better system of managing memory, a pointer can store an array of almost any size; this is tremendous when dealing with arrays of characters or a whole text. Using this feature, when declaring a pointer in replacement of an array, you do not have to worry about the size of the array, the compiler will take care of that. Again, this feature allows you to pass pointers to a function (just like arrays) and return a value that has been altered even if the function is declared as void. This is even more dynamic with multidimensional arrays.

Definition
Pointers are not particularly useful when declared and used inside of one function. They show their capabilities when different functions (and/or objects) exchange data stored in those pointers. As you can see from the execution of the program above, the address of a variable is very difficult to read and interpret. Fortunately, we don't need to know that address and we don't need to know what it means or where the variable is located. C++ provides an alternative to this problem. Instead of referring to a variable's address directly, you are allowed to declare another variable, and then use that new variable to refer to the address of the variable you are interested in. A pointer is a variable that refers to another variable's address. Just like any variable in C++, you should declare and initialize a pointer variable before using it. To declare a pointer variable, use an identifier, followed by an asterisk (*), followed by the name of the pointer, and a semi-colon. Here is the formula:
DataType * PointerName;

The identifier should be one of those we have learned already. This means it could be an int, a char, a double, etc. The identifier should be the same type of identifier the pointer variable will point to. Therefore, if you are declaring a pointer that will point to an integer variable, the pointer identifier should be an integer. The asterisk (*) lets the compiler know that the variable that follows is a pointer. There are three ways you can type the asterisk. These are
DataType* PointerName; DataType * PointerName; DataType *pointerName;

By default, it does not matter how you append the *, the compiler will know that the thing that follows is a variable. Be careful when declaring various pointers. If you declare a few of them on the same line, like this:
DataType* pointer1, pointer2;

Only the first variable is a pointer, the second is a regular variable. If you want to declare different variables, you use:
DataType* pointer1, *pointer2;

Or
DataType* pointer1; DataType* pointer2;

Since the name of the pointer is indeed the name of a variable, you will follow the naming rules that govern every C++ variable.
#include <iostream> using namespace std;

int main() { int value; int *pointer;

cout << "Value lives at " << &value << "\n";

cout << "Pointer lives at " << &pointer;

cout << "\n\n"; return 0; }

After executing the program, you might get:


Value lives at: 0x0065FDF4 Pointer lives at: 0x0065FDF0

Initializing a Pointer
One of the reasons you are using a pointer is to find an alternative to knowing the address of a variable. Therefore, from now on, we are not interested in a variable's real address. Instead, we will use a pointer to point to that variable. As we have learned already, a variable should be initialized before being used. This allows the compiler to put something into the memory space allocated for that variable. To use a pointer P effectively, for its intended purpose, you need to tell the compiler that: pointer P will be used to point to the address of variable V. You do this by initializing the pointer. A pointer is initialized (almost) like any other variable, using the assignment operator (=). There are two main ways you can initialize a pointer. When declaring a pointer like this:
int* Pointer;

initialize it by following the assignment operator with & operator and the name of the variable, like this
int* Pointer = &Variable;

You can also initialize a pointer on a different line, after declaring it. This time, you should not use the asterisk on the Pointer, but the compiler should know that the pointer will point to a variable's address; therefore, the name of the variable will still use the &.
#include <iostream> using namespace std;

int main() { int value = 12; int *pointer = &value;

cout << "Value lives at: " << value << "\n"; cout << "Pointer lives at: " << *pointer; cout << "\n\n"; return 0; }

The program would produce:


Value lives at: 12

Pointer lives at: 12

This program could also have the pointer initialized as:


#include <iostream> using namespace std;

int main() { int Value = 12; int *pointer;

cout << "Value lives at: " << value << "\n";

Pointer = &value; cout << "Pointer lives at: " << *pointer; cout << "\n\n"; return 0; }

And it would produce the same result. As another of the program, you can first declare both variables, then initialize them later on, when needed:
#include <iostream> using namespace std;

int main() { int value; int *pointer;

pointer = &value; Value = 26; cout << "Value = " << value << "\n"; cout << "*Pointer = " << *pointer << "\n";

cout << "\n"; return 0;

Once you have declare a variable and assign it to a pointer, during the course of your program, the value of a variable is likely to change, you can therefore assign it a different value:
#include <iostream> using namespace std;

int main() { int value; int *pointer;

Pointer = &value; Value = 26; cout << "Value = " << value << "\n"; cout << "*pointer = " << *pointer << "\n";

Value = 35; cout << "Value = " << value << "\n"; cout << "*pointer = " << *pointer << "\n";

cout << "\n"; return 0; }

As you know now, both *pointer and Value have the same value. This allows you to change the value of the pointer directly and affect the main variable meanwhile. Therefore, you can safely change the value of the pointer and it will be assigned accordingly. To see an example, make the following change to the file:
#include <iostream> using namespace std;

int main() { int value; int *pointer;

Pointer = &value; Value = 26; cout << "Value = " << value << "\n"; cout << "*pointer = " << *pointer << "\n";

Value = 35; cout << "Value = " << value << "\n"; cout << "*pointer = " << *pointer << "\n";

*pointer = 144; cout << "Value = " << value << "\n"; cout << "*pointer = " << *pointer << "\n";

cout << "\n"; return 0; }

This would produce:


Value = 26 *pointer = 26 Value = 35 *pointer = 35 Value = 144 *pointer = 144

A Pointer to a Pointer
Instead of pointing to a regular variable, a pointer can be made to point to another pointer. To apply this, always remember that you must specify what target a pointer is pointing to. Once again, consider the following example:
#include <iostream> using namespace std;

int main() { int value = 26; int *pointer;

pointer = &value;

cout << " Value

= " << value << "\n";

cout << "*Pointer = " << *pointer << "\n";

return 0; }

This would produce:


Value = 26 *Pointer = 26

In this program, if necessary, you can declare a new variable that is a pointer that itself points to another pointer. When declaring such a variable, precede it with two *. After declaring the pointer, before using it, you must initialize it with a reference to a pointer, that is, a reference to a variable that was declared as a pointer. Here is an example:
#include <iostream> using namespace std;

int main() { int value = 26; int *pointer; int **pointerToPointer;

pointer = &value; pointerToPointer = &pointer;

cout << "

Value

= " << value << "\n";

cout << " *Pointer = " << *pointer << "\n"; cout << "**Pointer = " << **pointerToPointer << "\n";

return 0; }

This would produce:


Value = 26 *Pointer = 26 **Pointer = 26

Just as demonstrated earlier, after initializing a pointer, if you change the value of the variable it points to, the pointer would be updated. Consider the following program:
#include <iostream> using namespace std;

int main() { int value = 26; int *pointer; int **pointerToPointer;

pointer = &value; pointerToPointer = &pointer;

cout << "

Value

= " << value << "\n";

cout << " *Pointer = " << *pointer << "\n"; cout << "**Pointer = " << **pointerToPointer << "\n";

value = 4805;

cout << "After changing the value of the main variable...\n"; cout << " Value = " << value << "\n";

cout << " *Pointer = " << *pointer << "\n"; cout << "**Pointer = " << **pointerToPointer << "\n";

return 0; }

This would produce:


Value = 26 *Pointer = 26 **Pointer = 26 After changing the value of the main variable... Value = 4805

*Pointer = 4805 **Pointer = 4805

Notice that, by changing the value of the original variable, when accessing its pointer or the pointer to its pointer, they reflect the new value. In the same way, instead of (directly) changing the value of the variable, you can change the value of its pointer. You can also change the value of the pointer to its pointer. Like a chain reaction, all variables would be updated. Consider the following program:
#include <iostream> using namespace std;

int main() { int value = 26; int *pointer; int **pointerToPointer;

pointer = &value; pointerToPointer = &pointer;

cout << " Value

= " << value << "\n";

cout << " *Pointer = " << *pointer << "\n"; cout << "**Pointer = " << **pointerToPointer << "\n";

value = 4805;

cout << "\nAfter changing the value of the main variable...\n"; cout << " Value = " << value << "\n";

cout << " *Pointer = " << *pointer << "\n"; cout << "**Pointer = " << **pointerToPointer << "\n";

*pointer = -728;

cout << "\nAfter changing the value of the pointer...\n"; cout << " Value = " << value << "\n";

cout << " *Pointer = " << *pointer << "\n"; cout << "**Pointer = " << **pointerToPointer << "\n";

**pointerToPointer = 945580;

cout << "\nAfter changing the value of the pointer to pointer...\n"; cout << " Value = " << value << "\n";

cout << " *Pointer = " << *pointer << "\n"; cout << "**Pointer = " << **pointerToPointer << "\n";

return 0; }

This would produce:


Value = 26 *Pointer = 26 **Pointer = 26

After changing the value of the main variable... Value = 4805

*Pointer = 4805 **Pointer = 4805

After changing the value of the pointer... Value = -728

*Pointer = -728 **Pointer = -728

After changing the value of the pointer to pointer... Value = 945580

*Pointer = 945580 **Pointer = 945580

Operations on Pointers
Introduction
Consider that, added just a few rules, a pointer is a variable like any other: it can get its valuefrom the user (indirectly), you can apply any of the algebraic operations we have learned, it can be incremented, it can be applied on a function, etc. A variable is a value that is supposed to change some time to time. Since a pointer is a

variable whose value points to another variable, the value of a pointer is affected by the variable it points to. You can use this indirection to change the value of a pointer when changing its main variable. To get a value from the user, we have already learned that you can use the cin operator. When using a pointer to get a value from the user, don't forget the * operator, otherwise, the compiler would get confused. We have already learned how to request and display the value of a regular variable from the user:
#include <iostream> using namespace std;

int main() { int students;

cout << "Number of students: "; cin >> students;

cout << "\nNumber of students: " << students;

cout << "\n\n"; return 0; }

Once you have gotten a value and store it in a variable, it is available:


#include <iostream> using namespace std;

int main() { int students; int *ptrStudents;

ptrStudents = &students; cout << "Number of students: "; cin >> students; cout << "\nNumber of students: " << students << "\nThat is: " << *ptrStudents << " students.";

cout << "\n\n"; return 0; }

This could produce:


Number of students: 24

Number of students: 24 That is: 24 students

In the same way, you can request a value from the user and store it in the pointer. To see an example, make the following change to the file:
#include <iostream> using namespace std;

int main() { int students; int *ptrStudents;

ptrStudents = &students; cout << "Number of students: "; cin >> *ptrStudents;

cout << "\nNumber of students: " << students << "\nThat is: " << *ptrStudents << " students.";

cout << "\n\n"; return 0; }

Of course, you can use various pointers on the same program. Apply an example by making the following changes:
#include <iostream> using namespace std;

int main() { int boys;

int girls; int *ptrBoys; int *ptrGirls;

ptrBoys = &boys; ptrGirls = &girls;

cout << "Number of male students: "; cin >> *ptrboys;

cout << "Number of female students: "; cin >> *ptrGirls; cout << "\nNumber of students:";

cout << "\nBoys:" << "\t" << Boys << "\nThat is: " << *ptrBoys << " students."; cout << "\nGirls:" << "\t" << Girls << "\nThat is: " << *ptrGirls << " students.";

cout << "\n\n"; return 0; }

We have learned how to perform algebraic calculations and expressions in C++. When performing these operations on pointers, remember to use the * for each pointer involved. The calculations should be as smooth:
#include <iostream> using namespace std;

int main() { int boys; int girls; int total; int *ptrBoys; int *ptrGirls;

int *ptrTotal;

ptrBoys = &boys; ptrGirls = &girls; ptrTotal = &total;

cout << "Number of male students: "; cin >> *ptrBoys; cout << "Number of female students: "; cin >> *ptrGirls;

cout << "\nNumber of students:"; cout << "\nBoys:" << "\t" << Boys << "\nThat is: " << *ptrBoys << " students."; cout << "\nGirls:" << "\t" << Girls << "\nThat is: " << *ptrGirls << " students.";

Total = Boys + Girls;

*ptrTotal = *ptrBoys + *ptrGirls;

cout << "\n\nTotal number of students: " << total; cout << "\nThere are " << *ptrTotal << " students";

cout << "\n\n"; return 0; }

This would produce:


Number of male students: 26 Number of female students: 24

Boys: 26 That is: 26 students

Girls: 24 That is: 24 students

Total number of students: 50 There are 50 students

Passing Pointers to Functions


We know that a function uses arguments in order to carry its assignment. The arguments are usually provided to the function. When necessary, a function also declares its own variable to get the desired return value. Like other variables, pointers can be provided to a function, with just a few rules. When declaring a function that takes a pointer as an argument, make sure you use the asterisk for the argument or for each argument. When calling the function, use the references to the variables. 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 a starting file from what we have learned so far:
#include <iostream> using namespace std;

int main() { int shirts = 12; int pants = 5;

cout << "Shirts = " << shirts << endl; cout << "Pants = " << pants << endl;

cout << endl; return 0; }

This would produce:


Shirts = 12 Pants = 5

To pass arguments to a function, you can make the following changes:


#include <iostream> using namespace std;

int main() { int shirts = 3; int pants = 5; void Deposit(int s, int p);

cout << "When starting, within main():\n"; cout << "\tShirts = " << shirts << endl; cout << "\tPants = " << pants << endl;

Deposit(Shirts, Pants);

cout << "\n\nAfter calling Deposit(), within main():\n"; cout << "\tShirts = " << shirts << endl;

cout << "\tPants = " << pants << endl; cout << endl; return 0; }

void Deposit(int s, int p) { s = 8; p = 12;

cout << "Within Deposit()" << "\n\tShirts = " << s << "\n\tPants = " << p; }

After executing, the program would produce:


When starting, within main(): Shirts = 3 Pants = 5

Within Deposit() Shirts = 8 Pants = 12 After calling Deposit(), Within main(): Shirts = 3 Pants = 5

To pass pointer arguments, use the asterisks when declaring the function, and use the ampersand & when calling the function. Here is an example:
#include <iostream> using namespace std;

int main() { int shirts = 12; int pants = 5; void Deposit(int s, int p); void Pickup(int *sht, int *pt);

cout << "When starting, within main():\n"; cout << "\tShirts = " << shirts << endl; cout << "\tPants = " << pants << endl;

Deposit(shirts, pants); cout << "\n\nAfter calling Deposit(), within main():\n"; cout << "\tShirts = " << shirts << endl; cout << "\tPants = " << pants << endl;

Pickup(&shirts, &pants); cout << "\n\nAfter calling Pickup(), within main():\n"; cout << "\tShirts = " << shirts << endl; cout << "\tPants = " << pants << endl;

cout << endl;

return 0; }

void Deposit(int s, int p) { s = 8; p = 5;

cout << "\nWithin Deposit()" << "\n\tShirts = " << s << "\n\tPants = " << p; }

void Pickup(int *sht, int *pt) { *sht *pt = 26; = 17;

cout << "\nWithin Pickup()" << "\n\tShirts = " << *sht << "\n\tPants = " << *pt; }

The result of executing the program is:


When starting, within main(): Shirts = 12 Pants = 5

Within Deposit() Shirts = 8 Pants = 5

After calling Deposit(), within main(): Shirts = 12 Pants = 5

Within Pickup() Shirts = 26 Pants = 17

After calling Pickup(), within main(): Shirts = 26 Pants = 17

A Function That Returns a Pointer


If you want a function to return a pointer, when declaring the function, make sure that you specify its return type as a pointer and you can use a type of your choice. Here is an example of such a declaration:
#include <iostream> using namespace std;

int main() { int *GetNumber();

return 0; }

In this case, we have declared a function named GetNumber that will return a pointer to int. When implementing the function, you can apply any of the techniques we have used so far inside the function. The most important rule to keep in mind is that the function must return a pointer and not a regular value. In the same way, when calling a function that returns a pointer, you can use its value only where the returned pointer is appropriate. For example, you can assign its returned value only to a pointer of the same type. Here is an example:
#include <iostream> using namespace std;

int main() { int *GetNumber(); int *number;

number = GetNumber();

cout << "Number = " << *number << endl;

return 0; }

int *GetNumber() { int *a = new int(2885);

return a; }

This would produce:


Number = 2885

Pointers and Memory Management


By definition, the variables in your program are meant to "vary", that is, their values change regularly. When you declare a variable, such as
int Shirts;

the compiler reserves an appropriate amount of memory space for that particular variable. This is done when the program is compiling but before its execution. This means of providing memory space is called static allocation, the memory space is "allocated" to that variable. When the program executes, this static memory allocation does not change; but the memory space might be empty, especially if the variable is not initialized. This is important: the fact that a variable is not initialized means its memory space is empty, it is not equal to zero; it is simply empty. Nothing is occupying it. You can also ask the compiler to provide memory when the program is executing. This is called dynamic allocation. Dynamic allocation is performed using the new operator like this:
PointerName = new DataType;

The keyword new is required. The data type can be any of those we are already familiar with, but it must be appropriate to the variable it is pointing to. This means that, if it is pointing to an integer variable, the data type must be an integer. For example, our corresponding dynamic allocation would be:
ptrShirts = new int;

After dynamically allocating memory, you can assign a new value to the pointer for any purpose. Once the memory is not anymore in use, you should reclaim it. This is done with thedelete keyword, like this:
delete ptrShirts;

Here is a starting point for this section :


#include <iostream> using namespace std;

int main() { int studentAge = 12;

cout << "Student age = " << studentAge << endl;

cout << endl; return 0; }

Now, let's add a pointer and try to access it without initializing it:
#include <iostream> using namespace std;

int main() { int studentAge = 12; int* age;

cout << "Student age = " << studentAge << endl; cout << "*Age = " << *age << endl;

cout << endl; return 0; }

You will get a value that is not insignificant. Depending on the compiler, you might even get a nasty dialog box and a warning. This is because you were trying to access a pointer that has not been initialized. You can initialize the pointer like this:
#include <iostream> using namespace std;

int main() { int studentAge = 12; int* age;

Age = &studentAge;

cout << "Student age = " << studentAge << endl;

cout << "*Age = " << *age << endl;

cout << endl; return 0; }

To illustrate that an un-initialized variable has an address (although empty), you can change the file as follows:
#include <iostream> using namespace std;

int main() { int studentAge; int* ptrAge;

ptrAge = &studentAge;

cout << "Student age = " << studentAge << endl; cout << "*ptrAge = " << *ptrAge << endl;

cout << endl; return 0; }

When you initialize a variable, its value gets stored in the memory space that was statically allocated by the compiler. In the same way, since its corresponding pointer points to its address, you can initialize the pointer and still access the value assigned to the variable it is pointing to. To see an example of a pointer, and not the variable itself being initialized, make the following changes to the file:
#include <iostream> using namespace std;

int main() { int studentAge; int *age;

age = &studentAge; cout << "Student age = " << studentAge << endl; cout << "*Age = " << *age << endl;

*Age = 15; cout << "Student age = " << studentAge << endl; cout << "*Age cout << "\n"; return 0; } = " << *age << endl;

This results in:


Student age = -858993460 *Age = -858993460

Student age = 15 *Age = 15

To dynamically allocate memory, you assign the pointer with the new keyword followed by the appropriate identifier:
#include <iostream> using namespace std;

int main() { int studentAge; int *age;

age = &studentAge; cout << "Student age = " << studentAge << endl; cout << "*Age = " << *age << endl;

*age = 15; cout << "Student age = " << studentAge << endl; cout << "*Age = " << *age << endl;

age = new int;

cout << "Student age = " << studentAge << endl; cout << "*Age cout << "\n"; return 0; } = " << *age << endl;

As you can see, since the value of the pointer has been dynamically assigned, its address is now empty. If you want to access its content, you have to reassign it another value; this is one of the mistakes that happen regularly in a program. When this happens, the program will compile fine, without any error or warning, but the result Therefore, you should always know the value of a pointer. In our example, you can reassign a value to the empty pointer:
age = new int; *Age = 17; cout << "Student age = " << studentAge << endl; cout << "*Age cout << "\n"; } = " << *age << endl;

After using a pointer, don't forget to clean your memory. You do this using the delete operator:
#include <iostream.h> int main() { int studentAge; int *age; age = &studentAge; cout << "Student age = " << studentAge << endl; cout << "*Age = " << *age << endl; *age = 15; cout << "Student age = " << studentAge << endl; cout << "*Age = " << *age << endl; Age = new int; *age = 17; cout << "Student age = " << studentAge << endl; cout << "*Age = " << *age << endl; delete age; cout << "\n"; return 0; }

Here is an example of an array as we learned when studying them: #include <iostream> using namespace std; int main()

{ int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; cout cout cout cout cout cout cout cout cout cout cout cout cout } In this case, the Number variable is an array of 12 integer values. Because a variable declared as array is first of all a variable, using its name, let us find its address. Consider the following program: #include <iostream> using namespace std; int main() { int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; cout << "\n Number : cout << "\n&Number : cout << "\n&number[0] : return 0; } This would produce: Number : 1245020 &Number : 1245020 " << Number; " << &Number; " << &number[0] << endl; << << << << << << << << << << << << << "List of Numbers"; "\nNumber 1: " << "\nNumber 2: " << "\nNumber 3: " << "\nNumber 4: " << "\nNumber 5: " << "\nNumber 6: " << "\nNumber 7: " << "\nNumber 8: " << "\nNumber 9: " << "\nNumber 10: " << "\nNumber 11: " << "\nNumber 12: " << number[0]; number[1]; number[2]; number[3]; number[4]; number[5]; number[6]; number[7]; number[8]; number[9]; number[10]; number[11];

return 0;

&number[0] : 1245020 This demonstrates that Number, &Number, and &number[0] have the same value. As we learned with pointers, the use of the ampersand "&" allows us to get the address of a variable. Therefore, &Number gives us the address of the array variable. Furthermore, since &Number and &number[0] have the same value, and seeing that all three (Number, &Number, and &number[0]) have the same value, this demonstrates that the name of the variable in fact carries, or holds, or represents, the address of the first value of the array. In fact, consider the following program: #include <iostream>

using namespace std;

int main() { int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

cout << "An integer occupies " << sizeof(int) << " bytes\n"; cout << "\n Number: " << Number;

cout << "\n&number[0]: " << &number[0] << endl; cout << "\n Number+1: " << Number+1;

cout << "\n&Number:[1] " << &number[1] << endl; cout << "\n Number+2: " << Number+2;

cout << "\n&Number:[2] " << &number[2] << endl;

return 0; } This would produce: An integer occupies 4 bytes

Number:

1245020

&number[0]: 1245020

Number+1:

1245024

&Number:[1] 1245024

Number+2:

1245028

&Number:[2] 1245028 Notice that, by adding numbers to the name of the variable, we are able to get the address of any member of the array.

Relating a Pointer to an Array

Now that we know that the name of an array holds the address of the first member of the array, we realize that we can declare a pointer of the same data type as the array and initialize it with the array. Here is an example: int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; After this declaration and initialization, Number and pNumbers have the same value:

#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; " << pNumbers;

cout << "\npNumbers :

return 0; } This would produce: Addresses Number : 1245020 1245020

pNumbers :

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]; " << *pNumbers;

cout << "\n*pNumber

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; " << pNumbers;

cout << "\npNumbers :

cout << "\n\nValues"; cout << "\n Number [0] : cout << "\npNumbers[0] : cout << "\n Number [1] : cout << "\npNumbers[1] : " << number[0]; " << pNumbers[0]; " << number[1]; " << pNumbers[1];

return 0; } This would produce: Addresses Number : 1245020 1245020

pNumbers :

Values Number [0] : pNumbers[0] : Number [1] : 31 31 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 cout << "\npNumbers : : " << Number; " << pNumbers; " << Number+1; " << pNumbers+1; " << Number+2; " << pNumbers+2;

cout << "\n Number +1 : cout << "\npNumbers+1 : cout << "\n Number +2 : cout << "\npNumbers+2 :

return 0; } This would produce: Addresses Number pNumbers : : 1245020 1245020 1245024 1245024 1245028

Number +1 : pNumbers+1 : Number +2 :

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 thecompiler 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]: cout << "\n number[1]: cout << "\n number[2]: cout << "\n number[3]: cout << "\n number[4]: " << number[0]; " << number[1]; " << number[2]; " << number[3]; " << number[4];

cout << "\n\nValues - Using the Pointer - No Parentheses"; cout << "\n*pNumbers: " << *pNumbers;

cout << "\n*pNumbers+1: cout << "\n*pNumbers+2: cout << "\n*pNumbers+3: cout << "\n*pNumbers+4:

" << *pNumbers+1; " << *pNumbers+2; " << *pNumbers+3; " << *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]: number[1]: number[2]: number[3]: number[4]: 31 28 31 30 31

Values - Using the Pointer - No Parentheses *pNumbers: *pNumbers+1: *pNumbers+2: *pNumbers+3: *pNumbers+4: 31 32 33 34 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 desiredreturn 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

Practical Learning: Passing Pointers as Arguments


1. Create a new project named Fire Insurance2 2. Create a C++ source file named Main.cpp 3. 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: cout << "\nPolicy: cout << "\nPremium: $" << Coverage; $" << Policy; $" << 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; } 4. 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: Policy: Premium: $92 $45000 $268.95

******************************** 5. Return to your programming environment 6. 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: cout << "Enter the policy amount: $"; cin >> Coverage; $"; cin >> Policy;

Premium = CalculatePremium(&Rate, &Coverage, &Policy);

cout << "\n********************************"; cout << "\nFire Insurance - Customer Quote"; cout << "\n________________________________";

cout << "\nAnnual Premium: $" << Rate; cout << "\nCoverage: cout << "\nPolicy: cout << "\nPremium: $" << Coverage; $" << Policy; $" << 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; } 7. 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.

Practical Learning: Passing Reference Pointers to Functions


1. 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: cout << "\nPolicy: cout << "\nPremium: $" << Coverage; $" << Policy; $" << 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; } 2. 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: Premium:

$60000 $370

********************************

Press any key to continue...

Constant Pointers as Arguments

3. Return to your programming environment

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 executionbecause 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 constkeyword 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); }

Practical Learning: Passing Constant Pointers


1. 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: cout << "\nPolicy: cout << "\nPremium: $" << Coverage; $" << Policy; $" << 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; } 2. Test the application and return to your programming environment 3. 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] (*pNumbers)[1] (*pNumbers)[2] (*pNumbers)[3] (*pNumbers)[4] (*pNumbers)[5] = number[0][0]; = number[0][1]; = number[0][2]; = number[0][3]; = number[0][4]; = 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] cout << "\n(*pNumbers)[1] cout << "\n(*pNumbers)[2] cout << "\n(*pNumbers)[3] cout << "\n(*pNumbers)[4] cout << "\n(*pNumbers)[5] = " << (*pNumbers)[0]; = " << (*pNumbers)[1]; = " << (*pNumbers)[2]; = " << (*pNumbers)[3]; = " << (*pNumbers)[4]; = " << (*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] (*pNumbers)[1] (*pNumbers)[2] (*pNumbers)[3] (*pNumbers)[4] (*pNumbers)[5]

= 31 = 28 = 31 = 30 = 31 = 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 todynamically 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] pNumbers[1] pNumbers[2] pNumbers[3] *(pNumbers+4) *(pNumbers+5) *(pNumbers+6) *(pNumbers+7)

= 31; = 29; = 31; = 30; = 31; = 30; = 31; = 31;

*(pNumbers+8) *(pNumbers+9)

= 30; = 31;

pNumbers[10] = 30; pNumbers[11] = 31;

cout << "List of numbers"; cout << "\nNumber 1: cout << "\nNumber 2: cout << "\nNumber 3: cout << "\nNumber 4: cout << "\nNumber 5: cout << "\nNumber 6: cout << "\nNumber 7: cout << "\nNumber 8: cout << "\nNumber 9: " << *pNumbers; " << *(pNumbers+1); " << *(pNumbers+2); " << *(pNumbers+3); " << pNumbers[4]; " << pNumbers[5]; " << pNumbers[6]; " << pNumbers[7]; " << *(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: Number 2: Number 3: Number 4: Number 5: Number 6: Number 7: 31 29 31 30 31 30 31

Number 8: Number 9:

31 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] pNumbers[1] pNumbers[2] pNumbers[3] *(pNumbers+4) *(pNumbers+5) *(pNumbers+6) *(pNumbers+7) *(pNumbers+8) *(pNumbers+9)

= 31; = 28; = 31; = 30; = 31; = 30; = 31; = 31; = 30; = 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] (*pNumbers)[1] (*pNumbers)[2] (*pNumbers)[3] (*pNumbers)[4] (*pNumbers)[5] = 31; = 29; = 31; = 30; = 31; = 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] cout << "\n(*pNumbers)[1] cout << "\n(*pNumbers)[2] cout << "\n(*pNumbers)[3] cout << "\n(*pNumbers)[4] cout << "\n(*pNumbers)[5] = " << (*pNumbers)[0]; = " << (*pNumbers)[1]; = " << (*pNumbers)[2]; = " << (*pNumbers)[3]; = " << (*pNumbers)[4]; = " << (*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] (*pNumbers)[1] (*pNumbers)[2] (*pNumbers)[3] (*pNumbers)[4] (*pNumbers)[5] = 31 = 29 = 31 = 30 = 31 = 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 cout cout cout cout cout cout cout cout cout cout cout } 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); << << << << << << << << << << << << "\n(*pNumbers)[0] "\n(*pNumbers)[1] "\n(*pNumbers)[2] "\n(*pNumbers)[3] "\n(*pNumbers)[4] "\n(*pNumbers)[5] "\n(*(pNumbers+1))[0] "\n(*(pNumbers+1))[1] "\n(*(pNumbers+1))[2] "\n(*(pNumbers+1))[3] "\n(*(pNumbers+1))[4] "\n(*(pNumbers+1))[5] = = = = = = = = = = = = " " " " " " " " " " " " << << << << << << << << << << << << (*nbr)[0]; (*nbr)[1]; (*nbr)[2]; (*nbr)[3]; (*nbr)[4]; (*nbr)[5] << endl; (*(nbr+1))[0]; (*(nbr+1))[1]; (*(nbr+1))[2]; (*(nbr+1))[3]; (*(nbr+1))[4]; (*(nbr+1))[5] << endl;

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

Das könnte Ihnen auch gefallen