Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Declaring a Pointer To define a pointer, use an asterisk, (*), in the declaration to specify the variable will be a pointer to the specified

Declaring a Pointer

To define a pointer, use an asterisk, (*), in the declaration to specify the variable will be a pointer to the specified data type.

Code Illustration

int values[5] = {325, 879, 120, 459, 735};

int *valuePtr = values;

Recall that the name of an array holds the memory address of the first element of the array. The second statement then would store the memory address of the first value in the variable valuePtr.

The name of a pointer is an identifier and must follow the rules for defining an identifier. Some programmers place the letters ptr, a common abbreviation for pointer, at the end of the variable name, others prefix a pointer with p_ or ptr_, and there are those who do nothing to distinguish a pointer by its name. The naming of a pointer variable is a matter of programming style.

Once a pointer has been declared and initialized, it can be used to access the data to which it points. In order to access this value, the dereference operator, *, must be used to prefix the name of the pointer. From the code above, valuePtr holds the address of the first element of the values array; therefore, *valuePtr will access the value 325. Add the following to main and execute the program.

Code Illustration

cout

cout

The output generated should look something like the following.

Example of expected output.

0xbfad43e8

325

Where 0xbfad43e8 is a memory address displayed in hexadecimal.

Obtaining the Memory Address of a Variable

The address operator, &, is used to determine the memory address of a variable that is not an array. Add code necessary to use fixed and setprecision, then add the following to main and run the program to confirm the use of the address operator.

Code Illustration

double payRate = 7.25;

double *ratePtr = &payRate;

cout

cout

cout

Using a Pointer to Alter Data

Just as the dereference operator is used to retrieve data, so too is it used to store data. Add the following to function main and run the program.

Code Illustration

*ratePtr = 10.50;

cout

The pointer, ratePtr, is used to change the data stored in payRate. The output of payRate confirms the change.

Using a Pointer in an Expression

As previously shown, the value pointed to by a pointer variable can be retrieved by dereferencing the pointer. In the above code, the retrieved value was simply displayed to the screen; however, it can also be used in an expression. Add the following to main and execute the program.

Code Illustration

double grossPay;

grossPay = payRate * 40;

cout

grossPay = *ratePtr * 40;

cout

Pointer Arithmetic

It is possible to add to or subtract from a memory address stored in a pointer. These actions can be accomplished using the addition operator,+, subtraction operator, - and the increment and decrement operators, ++ and --. This is helpful when accessing arrays via pointers.

The increment operator has been used to add the value 1 to a variable. When used with a pointer, the increment operator adds the size of the data referenced to the memory address stored in the pointer, effectivelymovingthe pointer to the next data value. Building on the code from above, add the following to main and execute the program.

Code Illustration

cout

cout

valuePtr++;

cout

cout

We initialized valuePtr to the memory address of the first element of the array values. Incrementing valuePtr instructs the computer to add four bytes, the size of an integer, to the memory addressed stored in valuePtr. After the increment, valuePtr now points to the second element of the array.

The addition operator, +, works in a similar fashion. Add the following to function main and execute the program.

Code Illustration

cout

cout

cout

Note that the value stored in valuePtr is not modified by this code. valuePtr currently points to the second element in the array. The program interprets the instruction to add two, *(valuePtr + 2), as add two times the size of an integer to the contents of valuePtr and access that address; this would be the fourth element of the array. The next line of code allows the confirmation of the interpretation of the addition by displaying the value in the fourth element of the array.

The last line of code is included to demonstrate the need for the parenthesis when using the dereference operator when using the addition operator to alter the memory address. Add code to test the necessity of using parenthesis with the increment operator.

The subtraction and decrement operators perform in a similar manner.

Pointers as Parameters

As with any other variable, pointers may be passed to functions as parameters. In a previous lab, a memory addressed was passed to a function using a reference parameter. The idea here is the same, only the syntax has changed.

A pointer parameter is specified using the same syntax as a pointer declaration. Within the function itself, the pointer is used as before; the name of the pointer holds the memory address and the data can be accessed by dereferencing the pointer.

Add the following function to the program.

Code Illustration

void getPayRate(double *rate)

{

cout

cin >> *rate;

}

The function call must match the function definition. The function definition has specified that the function expects a memory address; the function call must therefore send the function a memory address. Add the following to main and execute the program.

Code Illustration

getPayRate(&payRate);

cout

Because the pointer is a memory address, changes to the data value within the function will be seen outside the function.

When passing an array via a pointer, the data values can be accessed using array notation or pointer notation. Add the following to the program.

Code Illustration

void displayArray(int *array, int size)

{

cout

for (int i=0; i

cout

cout

}

Add the following to function main and execute the program.

Code Illustration

displayArray(values, 5);

The name of an array holds the memory address of the first element of the array; therefore, the name of an array is essentially a pointer to the first element of the array. Recall that the index specified within the [] operator, in array notation, instructs the computer to move that many elements from the first element. The computer calculates the distance to move using the same method as pointer arithmetic; the index value is multiplied by the size of the data type to determine the distance to move from the memory address of the first element.

Just to help you practice with pointer math, replace the previous array notation version of displayArray with the following pointer notation version and execute the program.

Code Illustration

void displayArray(int *array, int size)

{

cout

for (int i=0; i

cout

cout

}

One final array notation option exists for the displayArray function. While an array name's value cannot change, a pointer's value can change. When an array is declared, the name of the array holds the memory address of the first element. If this value could be changed, there would be no way to retrieve the original memory address and data would be lost. The name of an array is a constant pointer. The pointer itself cannot change. When passing an array to a function, the memory address is passed to a pointer; this pointer is not a constant pointer and can be changed. There is no danger in changing the pointer's value (or memory address) in the function as the name of the array, in the calling function, still holds the original memory address. Replace the previous pointer notation version of displayArray with the following pointer notation version and execute the program.

Code Illustration

void displayArray(int *array, int size)

{

cout

for (int i=0; i

cout

cout

}

Dynamic Memory Allocation

A variable declaration reserves memory for a variable. The amount of memory to be reserved must be known by the programmer. However, there are instances when the programmer may not know the exact amount of memory that will be needed by those that will use the program. As an example, recall from a previous lab the declaration of an array to store student scores. As the number of students was unknown, the array was declared large enough to store scores for double the largest expected class size. This approach works well until the assumption of the expected class size is no longer valid.

A better approach might be to reserve the amount of memory needed at the time of the program's execution. In this example, that would require the program to first determine the number of students in the class, and then reserve that amount of memory. However, when declaring an array, the size must be an integer constant or literal; it cannot be a variable.

The new Operator

The new operator allows the program to dynamically, at run-time, reserve memory. The new operator has one operand on its right which specifies the amount, or size, of memory to allocate. The new operator returns the memory address of the allocated memory.

Syntax

pointerName = new size_to_allocate;

Where size_to_allocate is typically a data type and pointerName has been declared a pointer of that type.

Once allocated, the memory can be accessed via the pointer as discussed previously. It is important to note that memory allocated in this way is not initialized just as local variables are not. Be sure to initialize the memory before accessing it in an expression.

The delete Operator

Once memory has been allocated using new, the memory is accessible until it is released using the delete operator. The delete operator releases any memory obtained by new so that it can be used for other purposes either later in the program or by another process running concurrently on the computer.

Syntax

delete pointerName;

Add the following to function main and execute the program.

Code Illustration

double *dv = new double;

*dv = 88.25;

cout

cout

delete dv;

dv = nullptr; // NULL the pointer so that it cannot accidentally be dereferenced again.

delete must never be used to release any memory not obtained via new. The address nullptr is reserved so that any attempt to dereference a pointer to that address will fail. You should always set an owning pointer to nullptr after freeing the memory that it was managing, since the address of that (now deallocated) memory isstill storedin the pointer; leaving it intact opens you to the possibility of accidentally making use of a storage location that no longer belongs to your program.

new[] and delete[]

Use the [] operator in conjunction with new to dynamically allocate an array.

Syntax

arrayName = new data_type[size_of_array];

Where arrayName has been declared a pointer to the specified data type. This instruction will allocate size_of_array many elements of data_type. As with any array, the elements will occupy consecutive memory addresses. As with any locally declared variable, the memory is not initialized.

Use the [] operator in conjunction with delete to release any memory allocated with the new[] operator.

Syntax

delete [] arrayName;

Add the following to the program.

Code Illustration

void getData (int *array, int size)

{

for (int i=0; i;>

{

cout

cin >> array[i];

}

}

Add the following to function main and execute the program.

Code Illustration

int *moreValues = new int[10];

getData(moreValues,10);

displayArray(moreValues,10);

delete [] moreValues;

This code will reserve enough consecutive space in memory to store ten integers and the address of the first element will be stored in the pointer variable moreValues.

While this code will dynamically allocate memory for the array, the literal 10 in the code still forces the programmer to determine the amount of memory needed prior to execution of the program. With new the programmer is no longer constrained to use a constant or literal to specify the size of the array. Replace the previous code in main with the following and execute the program.

Code Illustration

int numberOfMoreValues;

cout

cin >> numberOfMoreValues;

int *moreValues = new int[numberOfMoreValues];

getData(moreValues,numberOfMoreValues);

displayArray(moreValues,numberOfMoreValues);

delete [] moreValues;

moreValues = nullptr; // NULL the pointer for safety.

With this code, the programmer is no longer forced to decided memory usage prior to the program's execution. Here, the user specifies the number of elements that will be needed; that amount of memory and only that amount of memory is reserved.

Memory allocated using new remains available until it is released. delete need not be used within the function using new. To demonstrate, modify the getData function as follows.

Code Illustration

int *getData (int &numberOfMoreValues)

{

cout

cin >> numberOfMoreValues;

int *dynamicArray = new int[numberOfMoreValues];

for (int i=0; i;>

{

cout

cin >> dynamicArray[i];

}

return dynamicArray;

}

Then modify main as follows and execute the program.

Code Illustration

int numberOfMoreValues;

int *moreValues = getData(numberOfMoreValues);

displayArray(moreValues,numberOfMoreValues);

delete [] moreValues;

moreValues = nullptr; // NULL the pointer for safety.

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Introduction to Wireless and Mobile Systems

Authors: Dharma P. Agrawal, Qing An Zeng

4th edition

1305087135, 978-1305087132, 9781305259621, 1305259629, 9781305537910 , 978-130508713

Students also viewed these Programming questions

Question

Draw a schematic diagram of I.C. engines and name the parts.

Answered: 1 week ago