7 Pointers
7.1 Introduction to Pointers
Objects, Sizes, and Addresses
Each variable (object) has an address and a size. The address is where it sits and the size is how many memory locations it takes up.
| address | … | 100 | 101 | 102 | 103 | 104 | 105 | … |
|---|---|---|---|---|---|---|---|---|
| memory | … | … |
Size Operator
- The size can be retrieved using the size operator
sizeof
#include <iostream>
using namespace std;
int main() {
char c;
cout << sizeof(char) << " " << sizeof(c) << endl;
int i;
cout << sizeof(int) << " " << sizeof(i) << endl;
double d;
cout << sizeof(double) << " " << sizeof(d) << endl;
return 0;
}Address Operator
- The address can be retrieved using the address operator
&
#include <iostream>
using namespace std;
int main() {
char c = 1;
cout << int(c) << " " << &c << endl;
int i = 2;
cout << i << " " << &i << endl;
double d = 3.0;
cout << d << " " << &d << endl;
return 0;
}What is Pointer
A pointer is a variable that stores addresses of memory locations (addresses of other objects).
- The null pointer does not point to anything
Pointer’s Usage
Pointers have several uses, including:
- Creating fast and efficient code
- Providing a convenient means for addressing many types of problems
- Supporting dynamic memory allocation
- Making expressions compact and succinct
Declaring Pointers
- A pointer being a variable needs to be declared like all variables do
⟨Pointed Type⟩ * ⟨Pointer Variable Name⟩;
- A pointer to void is a general-purpose pointer used to hold references to any data type.
void *pv;- Declare pointer type
typedef ⟨Pointed Type⟩ * ⟨Pointer Type Name⟩;
- Example
typedef int * IntPointer;
int *p1; // pointer to an integer
IntPointer p2; // pointer to an integerPointer Operators
| Operator | Name | Meaning |
|---|---|---|
* |
Dereference | Used to dereference a pointer |
-> |
Point-to | Used to access fields of a structure referenced by a pointer |
+, +=, ++ |
Addition, increment | Used to increment a pointer |
-, -=, -- |
Subtraction, decrement | Used to decrement a pointer |
== != |
Equality, inequality | Compares two pointers |
> >= < <= |
Greater than, greater than or equal, less than, less than or equal | Compares two pointers |
⟨data type⟩ |
Cast | To change the type of pointer |
Dereferencing a Pointer
int num = 5;
int *pi = #
*pi = *pi + 2;
printf("%d\n",*pi);Adding an integer to a pointer
int vector[] = {28, 41, 7};
int *pi = vector; // pi: 100
printf("%d\n",*pi); // Displays 28
pi += 1; // pi: 104
printf("%d\n",*pi); // Displays 41
pi += 1; // pi: 108
printf("%d\n",*pi); // Displays 7Subtracting an integer from a pointer
int vector[] = {28, 41, 7};
int *pi = vector + 2; // pi: 108
printf("%d\n",*pi); // Displays 7
pi--; // pi: 104
printf("%d\n",*pi); // Displays 41
pi--; // pi: 100
printf("%d\n",*pi); // Displays 28Subtracting two pointers
int vector[] = {28, 41, 7};
int *p0 = vector;
int *p1 = vector+1;
int *p2 = vector+2;
printf("p2-p0: %d\n",p2-p0); // p2-p0: 2
printf("p2-p1: %d\n",p2-p1); // p2-p1: 1
printf("p0-p1: %d\n",p0-p1); // p0-p1: -1Comparing Pointers
int vector[] = {28, 41, 7};
int *p0 = vector;
int *p1 = vector+1;
int *p2 = vector+2;
printf("p2>p0: %d\n",p2>p0); // p2>p0: 1
printf("p2<p0: %d\n",p2<p0); // p2<p0: 0
printf("p0>p1: %d\n",p0>p1); // p0>p1: 0Multilevel Pointer
A pointer can store the address of another pointer variable.
int num = 100;
int *p1;
int **p2;
int ***p3;
p1 = #
p2 = &p1;
p3 = &p2;7.2 Constants and Pointers
Const
Using the const keyword to protect variables from changing
| Pointer Type | Pointer Modifiable | Data Pointed to Modifiable |
|---|---|---|
| Pointer to a nonconstant | \checkmark | \checkmark |
| Pointer to a constant | \checkmark | X |
| Constant pointer to a nonconstant | X | \checkmark |
| Constant pointer to a constant | X | X |
Pointer to a constant
int num = 5;
const int limit = 500;
int *pi; // Pointer to an integer
const int *pci; // Pointer to a constant integer
pi = #
pci = &limit;Constant pointer to a nonconstant
int num = 5;
int *const cpi = #Constant pointer to a constant
const int limit = 500;
const int * const cpci = &limit;7.3 Pointers and Arrays
One-Dimensional Arrays
- Example
int array[5];
int *p = array + 2;- Technique
T * range_begin = array;
T * range_end = array + n; // n is the length of the array
for (T *p = range_begin; p < range_end; p++) {
// do something
}Pointer to Arrays
- Syntax
⟨Data Type⟩ (* ⟨Pointer Variable Name⟩)[⟨Size of Array⟩];
- Example
int (*p1)[10];
double (*p2)[50];Two-Dimensional Arrays
- Row major
- Column major
2D row major
\begin{align*} offset & \longleftrightarrow(row,column)\\ offset & =row\times N_{column}+column \end{align*}
2D column major
\begin{align*} offset & \longleftrightarrow(row,column)\\ offset & =column\times N_{row}+row \end{align*}
Multidimensional Arrays
int A[2][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 }
};int B[2][2][3] = {
{ { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } }
};7.4 Pointers and Functions
Passing Data by Value
void swap(int num1, int num2) {
int tmp;
tmp = num1;
num1 = num2;
num2 = tmp;
}
int main() {
int n1 = 5;
int n2 = 10;
swap(n1, n2);
return 0;
}Passing Data Using a Pointer
void swapWithPointers(int* pnum1, int* pnum2) {
int tmp;
tmp = *pnum1;
*pnum1 = *pnum2;
*pnum2 = tmp;
}
int main() {
int n1 = 5;
int n2 = 10;
swapWithPointers(&n1, &n2);
return 0;
}Passing a Pointer to a Constant
void passingAddressOfConstants(const int* num1, int* num2) {
*num2 = *num1;
}
int main() {
const int limit = 100;
int result = 5;
passingAddressOfConstants(&limit, &result);
return 0;
}Returning a Pointer
int* allocateArray(int size, int value) {
int* arr = new int[size];
for(int i=0; i<size; i++) {
arr[i] = value;
}
return arr;
}several potential problems can occur when returning a pointer from a function, including:
- Returning an uninitialized pointer
- Returning a pointer to an invalid address
- Returning a pointer to a local variable
- Returning a pointer but failing to free it
Function Pointers
A function pointer is a pointer that holds the address of a function.
⟨Return Type⟩ (* ⟨Pointer Variable Name⟩)(⟨...⟩);
int (*f1)(double); // Passed a double and
// returns an int
void (*f2)(char*); // Passed a pointer to char and
// returns void
double* (*f3)(int, int); // Passed two integers and
// returns a pointer to a double- Declare function pointer type
typedef ⟨Return Type⟩ * ⟨Pointer Type Name⟩(⟨...⟩);
Using a Function Pointer
int (*fptr1)(int);
int square(int num) {
return num*num;
}
int main() {
int n = 5;
fptr1 = square;
printf("%d squared is %d\n",n, fptr1(n));
}7.5 Pointers and Structures
Pointers and Structures
- Declare a structure
struct Person {
char firstName[100];
char lastName[100];
char title[10];
unsigned int age;
};- Declare a pointer
Person *p;Point-to Operator
- Access the fields of a structure variable
cout << p->title;
cout << (*p).age;- The awkwardness of this expression
(*p).ageshows the necessity of the->operator. - Remember that the operators
->and.for selecting members of structures have higher precedence than the dereferencing operator*.
| Expression | Meaning |
|---|---|
s->m |
|
*a.p |
|
(*s).m |
|
*s->p |
|
*(*s).p |
7.6 Workshop
Quiz
- What is a pointer?