Previous Lecture lect11 Next Lecture

lect11, Thu 05/09

Pointers

Announcement

HW02 will be released tonight and will be due on Gradescope on Monday, 5/13. The goal of the homework is to change initCoord and initBox to use pass-by-reference (see Lec 10 notes) instead of pointers. We recommend doing the homework first, since this will allow you to focus on implementing the logic and functionality of the Lab05, without getting lost on the syntax. Note: there is no need for *b or *coord or -> when passing the struct by reference.

Pointers

The good, bad and ugly about pointers

The good:

The bad:

The ugly

Quiz 4 to practice pointers and accessing structs through pointers

Practice with Pointers

Remember how we were able to get the memory address of any variable using the ampersand sign, when we passed the variable by reference? As it turns out, we can store those locations in something called pointers.

Pointers are data types just like ints or chars, but instead of numbers and characters, a pointer stores a memory address.

Write this down somewhere you can see it while you are programming, and keep referencing this statement: a pointer stores a memory address (represented by a hexadecimal value).

To create a pointer, specify the type of an object that the pointer will point to and add an asterisk (*).

int a = 80;
cout << &a << endl; //0x2a8c64d78a0a
int* p; //p (a pointer to an integer) was created
p = &a; //p now stores the address of a.
cout << p << endl; //0x2a8c64d78a0a, same address as above

What can we do with pointers? Well, we can access the things they point to using the asterisk.

int a = 80;
int* p = &a;
cout << p << endl; //0x2a8c64d78a0a
cout << *p << endl; //80

This is very important

This process of getting the variable stored in memory, which is pointed to by the address stored inside a pointer, is called dereferencing a pointer.

Look at the last example with a and p. *p is equivalent to a. Why? Because p == (&a), so *p == *(&a) This command is saying: “Get me the address of a (&a), and then get me what’s stored at that address (a)”

Let’s see how we can solve the same problem of swapping variables, this time, using pointers:

// swap-ptr.cpp
#include <iostream>
using namespace std;

void swapValue(int* x, int* y){
    cout << "x = " << x << endl;  // address of a
    cout << "*x = " << *x << endl; // value stored at a
    cout << "y = " << y << endl; // address of b
    cout << "*y = " << *y << endl; // value stored at b
    cout<< "&x = " << &x <<"  "<< "&y = " << &y <<endl;
    // the above line prints the address of the *pointers* x and y
    // note that their addresses are different from their _values_ (which are addresses) stored at x and y
    // remember that the addresses of a and b that we printed are the _values_/addresses stored at x and y

    int tmp = *x; //tmp stores 30
    *x = *y;
    *y = tmp;
}

int main() {
    int a=30, b=40;
    cout << "=== Before the swap ===" << endl;
    cout<< a <<"  "<< b <<endl;
    swapValue( &a, &b); //passing LOCATIONS OF a and b
    cout << "=== After the swap ===" << endl;
    cout<< a <<"  "<< b <<endl;
    cout<< "&a = " << &a <<"  "<< "&b = " << &b <<endl;
}

The following assignments took place “under the hood” during the call to swapValue:

int* x = &a;
int* y = &b;

We accessed the values stored in a and b by dereferencing x and y pointers, which store the locations of a and b respectively.

Let’s pause and review what we’ve learned:

Make sure this also makes sense and you understand when to use & and *, and what value each would provide.

Next time

Pointers and arrays

When we learned about arrays, we promised to come back to them once we’ve leanred about pointers. Here we are. The variable declared as an array is actually just a pointer to the first element.

int arr[] = {5,4,3}; // arr points to the first element (currently 5)
cout << arr << endl; //0x2a8c64d78a14
cout << &(arr[0]) << endl; // same as `arr`, 0x2a8c64d78a14

Note that when you run the above code, you will get different values, because the compiler will assign variables to different memory locations.

Final notes

Pointers and references are confusing! They are arguably the hardest topic of the course, and are used a lot in C++. They are not intuitive, and may not make sense at first. That’s okay. We will be using them a lot, and it will get better. Use the resourses you have, including these notes and slides, and ask for help. Don’t wait until the week of the midterm.

Key concepts:

Practice Questions

  1. What type of value gets printed for each line in the following code when it gets called?
    void print_pointers(string* str1)
    {
     cout << "str1: " << str1 << endl;
     cout << "*str1: " << *str1 << endl;
     cout << "&str1: " << &str1 << endl;
    }
    
  2. What is the output of the following program?
    int main()
    {
     int a = 10;
     int *b = &a;
     int c = a;
        
     cout << “b is: “ << *b << endl;
     cout << “c is: “ << c << endl;
     a += 20;
     cout << “b is: “ << *b << endl;
     cout << “c is: “ << c << endl;
    
     return 0;
    }