# Pointers

What is a Pointer?

The basic definition of a pointer is a variable that stores an address. Pointers are used to store the adresses of other variables. Normally a variable contains a specific value. A pointer on the other hand contains the memory address of a variable which, in turn, contains a specific value.

Principle of Least Privilege - code should be granted only the amount of privilege and access needed to accomplish its task, but no more.

• A variable name directly references a value
• A pointer indirectly references a value
• Referencing a value through a pointer is referred to as indirection
Declaring Pointers:
• Pointer declarations use the * operator described further below.
• ```  typeName* variableName;
```
• We can declare multiple variables of the same type on one line, but for a pointer you must include the * operator for each.
• ```  int x, y, z;       //declaration of three variables of type int
int* p, q, r;      //appears to declare three pointers to ints, but actually creates one pointer and two ints.
int * p, * q, * r; //correct way to declare three pointers to ints on one line
```
• The following is read from right to left as, countPtr is a pointer to int
• ```  int count;        //declaration of variable count
int* countPtr;    //declaration of pointer countPtr
```
• The notation can be confusing because of the placement of *. The following three declarations are identical. They all declare countPtr as a pointer to an int.
• ```  int* countPtr;
int *countPtr;
int * countPtr;
```
Pointer Operators:
• Unary operator
• Obtains the memory address of its operand
• Below, &y means "address of y"
• ```  int y = 5;  // declare variable y
int* yPtr;  // declare pointer variable yPtr

yPtr = &y;  // assign address of y to yPtr
```
• Note: Not the same as & in a reference variable declaration which is always preceded by a data-type name.
When declaring a reference, the & is part of the type.
• ```  int& count;
```
• indirection or dereferencing operator *
• Returns an alias for the object to which its pointer operand points
• In the declaration statement, the type appears before the *
• ```  std::cout << *yPtr << endl;  // prints the value of y

just as,

std::cout << y << endl;      // prints the vlaue of y
```
• After the declaration statement, the * is dereferencing the pointer to obtain the value
• You can return the actual data item or value by dereferencing the pointer
• ```  cout << "The data value is " << *yPtr;  // prints the value
```
• Repeating the code snippet from above, for simplicity suppose the address stored is 1234 (also see Fig 8.4 in text)
• ```  int y = 5;  // declare variable y
int* yPtr;  // declare pointer variable yPtr

yPtr = &y;  // assign address of y to yPtr

cout << "The pointer is: " << yPtr;     // prints the pointer
cout << "The data value is " << *yPtr;  // prints the value

// Output
// The pointer is: 1234  // actual output depends on address
// The value is: 5
```
• Can also be used on the left side of an assignment statement. The following assigns 9 to y:
• ```  *yPtr = 9;
```
Initializing Pointers:
• Pointers should be initialized to 0, NULL or an address when declared or in an assignment
• NULL Pointer
• ```  int* yPtr;
yPtr = 0;
--OR--
int* yPtr = 0;
```
• 0 is the only integer literal that can be assigned to a pointer
• A pointer with the value 0 or NULL points to nothing, i.e. null pointer
• Initializing a pointer to NULL is equivalent to initializing it to 0
• In C++, 0 is used by convention
• Typically a placeholder to initialize pointers until their actual values are known
• Initializing pointers prevents accessing unknown or unitialized areas of memory
• If a pointer's value is unknown, it will likely be random memory garbage and unsafe to dereference.
• Don't try to dereference a null pointer - results in a segmentation fault
• If you always set pointers to null or another valid target, you can test prior to dereferencing as in,
• ```  if (yPtr != 0)      // safe to dereference
cout << *yPtr;
```
• May be assigned to a pointer of the same type
• ```  int * xPtr, * yPtr;  // two pointers to int
xPtr = yPtr;         // both point to the same location
```
```  int y = 5;  // declare variable y
int* yPtr;  // declare pointer variable yPtr

yPtr = &y;  // assign address of y to yPtr
```
• Sample Executable
• ```// Fig. 8.4: fig08_04.cpp
// Pointer operators & and *.
#include <iostream>
using namespace std;

int main()
{
int a; // a is an integer
int *aPtr; // aPtr is an int * which is a pointer to an integer

a = 7; // assigned 7 to a
aPtr = &a; // assign the address of a to aPtr

cout << "The address of a is " << &a
<< "\nThe value of aPtr is " << aPtr;
cout << "\n\nThe value of a is " << a
<< "\nThe value of *aPtr is " << *aPtr;
cout << "\n\nShowing that * and & are inverses of "
<< "each other.\n&*aPtr = " << &*aPtr
<< "\n*&aPtr = " << *&aPtr << endl;
} // end main
```
Pass-by-Reference with Pointers:
• Principle of Least Privilege
• Use pointers and the dereference operator * to pass-by-reference
• When calling a function with an argument that should be modified, pass the address
• The name of an array is the address of the first element of that array
• ```// Fig. 8.7: fig08_07.cpp
// Pass-by-reference with a pointer argument used to cube a
// variable's value
#include <iostream>
using namespace std;

void cubeByReference( int * ); // prototype

int main()
{
int number = 5;

cout << "The original value of number is " << number;

cubeByReference( &number ); // pass number address to cubeByReference

cout << "\nThe new value of number is " << number << endl;
} // end main

// calculate cube of *nPtr; modifies variable number in main
void cubeByReference( int *nPtr )
{
*nPtr = *nPtr * *nPtr * *nPtr; // cube *nPtr
} // end function cubeByReference
```
• Compare to the follwing example using pass-by-value
• ```// Fig. 8.6: fig08_06.cpp
// Pass-by-value used to cube a variable
#include <iostream>
using namespace std;

int cubeByValue( int ); // prototype

int main()
{
int number = 5;

cout << "The original value of number is " << number;

number = cubeByValue( number ); // pass number by value to cubeByValue
cout << "\nThe new value of number is " << number << endl;
} // end main

// calculate and return cube of integer argument
int cubeByValue( int n )
{
return n * n * n; // cube local variable n and return result
} // end function cubeByValue```
constness of Pointers:
• Principle of Least Privilege
• The use of const enables you to inform the compiler that the value of a particular variable should NOT be modified
• Four ways to pass a pointer to a function:
• Nonconstant Pointer to Nonconstant Data
• Highest access granted
• Data can be modified through the dereferenced pointer
• Pointer can be modified to point to other data
• Read from right to left as "countPtr is a pointer to an integer"
```  int* countPtr;
```
• Nonconstant Pointer to Constant Data
• Pointer can be modified to point to other data
• The data to which it points can NOT be modified
• Useful when passing an array to a function that will access all elements of the array but shouldn't modify the data
• Read from right to left as "countPtr is a pointer to a constant integer"
```  const int* countPtr;
```
• Constant Pointer to Nonconstant Data
• Pointer always points to the same memory location
• Data can be modified
• Pointer can NOT be modified to point to other data
• Since the pointer is const it must be initialized when declared
• An example is array name which is a constant pointer to the beginning of the array
• Read from right to left as "countPtr is a constant pointer to a nonconstant integer"
```  int* const countPtr = &x;  //const pointer must be initialized when declared
```
• Constant Pointer to Constant Data
• Minimum access granted
• Pointer always points to the same memory location
• Data can NOT be modified
• Pointer can NOT be modified to point to other data
• Since the pointer is const it must be initialized when declared
• Read from right to left as "countPtr is a constant pointer to a constant integer"
```  const int* const countPtr = &x;  //const pointer must be initialized when declared
```
Pointer Arithmetic
• Certain arithmetic operations may be performed on pointers
• Pointer arithmetic is only meaningful when performed on pointers that point to an array
• Arithmetic Operations
• Incremented (++) or Decremented (--)
• Integer may be added to (+ or +=) or subtracted from (- or -=)
• One pointer may be subtracted from another of the same type resulting in the distance between the two in bytes
• Operations are not literal but instead add or subtract the number of units
• sizeof Operator
• determines the size of any data type, variable or constant in bytes during program compilation
• Fig 8.15