~~SLIDESHOW~~
~~NOTOC~~
====== Pointers 3 slides ======
Pointers, arrays, arithmetic.\\
Mithat Konar\\
October 23, 2021
===== Pointers and arrays =====
* Arrays and pointers are closely related.
* Array names are like a constant pointers:
* the block of memory where an array name points cannot be changed,
* what is stored there can change.
===== Pointers and arrays =====
The relationship is so close that you can use pointer operators with array names:
int nums[] = {2, 4, 6, 8};
cout << nums[0] << endl; // prints 2
cout << nums << endl; // prints address where the array storage begins
cout << *nums << endl; // prints 2
===== Pointers and arrays =====
You can use array subscripting operations with pointers:
int *myPtr = &nums[0]; // myPtr points to first element of nums
cout << *myPtr << endl; // prints 2
cout << myPtr[0] << endl; // prints 2
cout << myPtr[1] << endl; // prints 4
cout << myPtr[2] << endl; // prints 6
===== Pointers and arrays =====
The following are equivalent:
int *myPtr = &nums[0]; // myPtr points to first element of nums
int *myPtr = &*nums; // myPtr points to first element of nums
int *myPtr = nums; // myPtr points to first element of nums
===== Pointer arithmetic =====
* Pointer arithmetic works differently than normal arithmetic.
* ''+'', ''+='', ''-'', ''-='', ''++'', ''--'' do math in terms of the size of the pointed data type.
* E.g., adding 1 to a pointer makes it point to the next block of memory corresponding to the size of the underlying type.
/** Pointer arithmetic. */
#include
using namespace std;
int main()
{
int v[] = {2, 4, 6, 8, 12};
int *vPtr = v;
cout << *vPtr << endl; // prints 2
vPtr = vPtr + 3; // vPtr now points to address vPtr + 3*sizeof(int),
// i.e., v[3]
cout << *vPtr << endl; // prints v[3]
vPtr--; // vPtr now points to address vPtr - 1*sizeof(int),
// i.e., v[2]
cout << *vPtr << endl; // prints v[2]
cout << *(vPtr + 2) << endl; // prints v[4]
return 0;
}
===== Pointer arithmetic: pointer difference =====
Subtracting one pointer from another returns the number of elements between two addresses:
/** Subtracting pointers */
#include
using namespace std;
int main()
{
int v[] = {2, 4, 6, 8, 12, 0};
int *vPtr = &v[0];
int *vPtr2 = &v[3];
cout << vPtr2 - vPtr << endl; // prints 3
return 0;
}
===== Walking down an array =====
A common technique used to visit every element in an array is to //walk down an array// with a pointer:
/** Walking down an array. */
#include
using namespace std;
int main()
{
int v[] = {2, 4, 6, 8, 12};
int *vPtr = v;
for (int i = 0; i < 5; i++)
{
cout << *vPtr << endl;
vPtr++;
}
return 0;
}
Especially common with zero-terminated (i.e., NULL terminated) partially-filled arrays:
/** Walking down a null-terminated array. */
#include
using namespace std;
int main()
{
int v[20] = {2, 4, 6, 8, 12};
int *vPtr = v;
while (*vPtr != 0)
{
cout << *vPtr << endl;
vPtr++;
}
return 0;
}
===== Summary =====
The following examples below assume:
int vals[] = {4, 7, 11};
int *valptr = vals;
===== Array access techniques =====
^ Access technique ^ Example ^
| ''arrayName[N]'' |vals[2] = 17;
|
| ''pointerName[N]'' |valptr[2] = 17;
|
| ''arrayName'' and subscript arithmetic |*(vals + 2) = 17;
|
| ''pointerName'' and subscript arithmetic |*(valptr + 2) = 17;
|
===== Array arithmetic =====
^ Operation ^ Example ^
|pointer++
|valptr++; // points at 7
|
|pointer--
|valptr--; // now points at 4
|
|pointer + int
|cout << *(valptr + 2); // prints 11
|
|pointer += int
|valptr = vals; // points at 4
valptr += 2; // points at 11
|
|pointer - pointer
|cout << valptr - vals; // # of ints between valptr and vals
|