15: Pointers, Finals and Projects

What We Will Cover


Continuations

Questions from last class?

Questions on the Project?

  • Anyone completed their project and ready to present or show it to me early?
  • Do not forget to submit your project before presenting
  • Also make sure you have a printed project report (enhanced README.txt) for me

15.1: Pointers

Learner Outcomes

At the end of the lesson the student will be able to:

  • Declare pointers and initialize pointer variables
  • Code basic pointer operations
  • Describe dynamic memory management
  • Describe why pointers are useful

15.1.1: Introduction to Pointers

  • We can write lots of interesting programs with what we have learned about C++ so far
  • However, there are some programming problems that can only be solved with pointers
  • Pointers add powerful new capabilities to our C++ programs
  • For example, pointers let you share access to common data
  • However, with this increased power comes increased responsibility
  • Pointers allow new types of bugs that can be difficult to find
  • These bugs may corrupt memory and crash programs
  • We will discuss how to prevent the errors while making use of the increased power of pointers

Why Use Pointers

  • Pointers allow different sections of code to share information easily
  • For example, pointers enable complex "linked" data structures: linked lists and binary trees (CS-19) Click
  • Pointers allow us to use memory only when needed (CS-19) Click
  • Pointers also provide alternative (not always better) ways to perform some tasks
  • For example: returning multiple values from a function
    • In exercise 8.3 we wrote a swap() function using pass-by-reference
    • That function could be written using pointers instead
  • Another alternative example is adding items to a list as a program runs
  • We have used vectors for this task, but how is the vector written?
  • There are many uses of pointers, some of which we will look at today

Image
A pointer numPtr to variable num

Pointer Variables

  • Remember that computers store values in memory in a binary format
  • Computer memory is organized as a long list of bytes (byte=8 bits)
  • Each type of data is allocated a certain number of bytes, for example:
    • char: 1 byte
    • int: 4 bytes
    • double: 8 bytes
  • A variable is a name for a place in the computer's memory
  • We usually draw a variable, like num, as a box (see image)
  • Pointer variables, or pointers, store memory addresses rather than values
  • Pointers refer to, or "point to", a value stored in memory
  • Since pointers are variables we draw them as boxes too, like numPtr
  • However, with pointers we include an arrow from the box to the memory address referred to by the pointer

Pointer Variable Example

  • In the following example, variable num is stored at memory address 1000
  • Variable num contains the value 42
  • Variable numPtr contains the value 1000, which is the memory address of num
Variables in Memory and a Pointer
Memory address 1000 1004 1008 1012
Memory content 42 ... 1000 ...
Variable name num ... numPtr ...
curved arrow

Check Yourself

  1. Benefits of using pointers include ________.
    1. the ability to allocate memory while the program is running
    2. allowing different sections of a program to share information
    3. enabling complex "linked" data structures like linked lists and binary trees
    4. all of these
  2. True or false: once code is compiled, pointers are completely safe and will never cause a problem in a running program.
  3. A pointer is a variable whose value is a memory ________.

15.1.2: Pointer Declaration and Assignment

  • Pointer variables must be declared as a pointer type
  • To declare a pointer variable we put an asterisk (*) after the type and before the name
  • For example, to declare a pointer variable named numPtr:
    int *numPtr = NULL;
    
  • The asterisk (*) identifies the variable numPtr as a pointer
  • The data type can be any C++ data type like char, double, int, and so on
  • When defining a pointer it is important to assign it a valid address
  • If you do not have an address yet, then use NULL
  • NULL is a word defined as 0 and used to indicate "no pointer"
  • For C++11 and later, we should use nullptr instead
  • By assigning a value like NULL when defining pointers, we prevent a common pointer error
  • Note that we may declare multiple pointers in one statement:
  • int *p1 = NULL, *p2 = NULL, v1 = 0, v2 = 0;
  • v1 and v2 are variables of type int
  • p1 and p2 point to variables of type int

Assigning Variable Addresses to Pointers

  • We may use the "address of" operator (&) to assign addresses to pointers
  • For example:
    p1 = &v1;
    
  • p1 is now a pointer to v1
  • v1 may be called either v1 or "the variable pointed to by p1"
Memory address 1000 1004 1008 1012
Memory content 42 ... 1000 ...
Variable name v1 ... p1 ...
curved arrow

Printing Memory Addresses

  • A pointer contains a memory address and we may display its value using cout
  • cout << p1 << endl;
  • For example the above code may display:
    0x28cc54
    
  • Notice that memory addresses print in a hexadecimal format
  • The memory address displayed will change for different variables as shown below

Example Assigning Memory Addresses to Pointers

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;

int main() {
    int *p1 = NULL, *p2 = NULL, v1 = 0, v2 = 0;
    p1 = &v1;
    p2 = &v2;
    cout << p1 << endl;
    cout << p2 << endl;

    return 0;
}

Check Yourself

  1. A valid pointer definition is ________.
    1. *int numPtr = NULL;
    2. int *numPtr = NULL;
    3. int numPtr* = NULL;
    4. all of these
  2. A correct assignment of a memory address to a pointer is ________.
    1. p1 = &v1;
    2. p1& = v1;
    3. p1 = v1&;
    4. p1 = v1;
  3. The following code prints the memory ________ of variable a.
    int a = 1;
    int *p = &a;
    cout << p << endl;
    

15.1.3: Accessing Variables Through Pointers

  • C++ uses the * operator in yet another way with pointers
  • The phrase "The variable pointed to by p" is translated into C++ as "*p"
    • Here the * is known as the dereferencing operator, also known as the indirection operator
    • p is said to be dereferenced
  • Dereferencing means to retrieve the value from the memory address that is pointed to by the pointer
  • For example:
    int v = 1234;
    int *p = &v;
    cout << "*p=" << *p << endl;
    
    displays the output:
    *p=1234
    
  • When dereferenced, the pointer must point to a valid address or it's a runtime error.
  • When we dereference a pointer, we may use it like a regular variable
    *p = 42;
    cout << "*p=" << *p << endl;
    
    which prints:
    *p=42
    
  • Notice the output of v2 in the following code

Example Using Pointer Dereferencing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;

int main() {
    int *p1 = NULL, *p2 = NULL, v1, v2;
    v1 = 1234;
    v2 = 0;
    p1 = &v1; // v1 and *p1 now refer to the same variable
    p2 = &v2;
    *p2 = 42; // dereferenced pointer assigned a value
    cout << "v1=" << v1 << endl;
    cout << "*p1=" << *p1 << endl;
    cout << "v2=" << v2 << endl;
    cout << "*p2=" << *p2 << endl;

    return 0;
}

Solo Activity (4m)

On a piece of paper:

  1. Declare an integer variable myInt and initialize it to a value of your choice.
  2. Declare a pointer to an integer variable named myIntPtr and initialize it to the address of myInt.
  3. Write code to print out the address of myInt.
  4. Write code to print out the value of myInt using myIntPtr.

Have your deskmate verify your variable definitions and write their name on your paper as having verified your work.

Check Yourself

  1. The following code prints ________.
    int v = 1234;
    int *p = &v;
    cout << "*p=" << *p << endl;
    
  2. The following code prints ________.
    int v = 1234;
    int *p = &v;
    *p = 42;
    cout << "v=" << v << endl;
    
  3. The following code prints ________.
    int a = 1;
    int b = 2;
    int *p = &a;
    cout << *p << " ";
    p = &b;
    cout << *p << endl;
    
  4. The following code prints ________.
    int a = 1;
    int b = 2;
    int *p = &a;
    int *q = &b;
    *p = *q;
    cout << a << " " << b << endl;
    

15.1.4: Using the Assignment Operator

  • We may use the assignment operator (=) to assign the value of one pointer to another
  • For example, given:
    int *p1 = NULL, *p2 = NULL, v1;
    v1 = 1234;
    p1 = &v1;
    p2 = p1;
    
  • Now *p2, *p1, and v1 all refer to the same variable
  • Be careful when making assignments to pointer variables:
    p1 = p2;    // changes the location to which p1 points
    
    *p1 = *p2; // changes the value at the location to which p1 points
    

Diagram of pointer assignment

  • Notice the memory addresses of p1 and p2 in the following example

Example: Pointer Assignment vs. Dereferenced-Pointer Assignment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;

int main() {
    int *p1 = NULL, *p2 = NULL, v1, v2;

    cout << "First example:" << endl;
    p1 = &v1;
    p2 = &v2;
    *p1 = 84;
    *p2 = 99;
    p1 = p2;
    cout << "p1:" << p1 << "=" << *p1 << endl;
    cout << "p2:" << p2 << "=" << *p2 << endl;

    cout << "\nSecond example:" << endl;
    p1 = &v1;
    p2 = &v2;
    *p1 = 84;
    *p2 = 99;
    *p1 = *p2;
    cout << "p1:" << p1 << "=" << *p1 << endl;
    cout << "p2:" << p2 << "=" << *p2 << endl;

    return 0;
}

Check Yourself

  1. The following code prints ________.
    int a = 15;
    int *p = &a;
    int *q = &a;
    cout << *p + *q << endl;
    
  2. The following code prints ________.
    int a = 15;
    int *p = &a;
    int *q = &a;
    *p = *p + 10;
    cout << *q << endl;
    
  3. The following code prints ________.
    int a = 15;
    int *p = &a;
    cout << *p << " " << p << endl;
    
  4. The error in the following code is ________.
    int v = 1234;
    int *p = &v;
    p = 42;
    
    1. v = 1234;
    2. *p = &v;
    3. p = 42;
    4. nothing is wrong

15.1.5: Arrays and Pointers

  • Recall that array elements are stored sequentially in memory addresses
  • For example the code
    int a[5] = { 10, 20, 30, 40, 50};
    
  • Creates an array in memory like the following
Memory address 1000 1004 1008 1012 1016
Memory content 10 20 30 40 50
Variable name a[0] a[1] a[2] a[3] a[4]
  • As we know, code like a[2] accesses an array element
  • However, an array name without brackets is a pointer to the first array element
  • We may capture that pointer in a variable
    int *p = a; // Now p points to a[0]
    
  • We may also use the array name as a pointer like:
    cout << *a << endl;
    
  • The above has the same effect as:
    cout << a[0] << endl;
    
  • We may even use pointer p as a substitute for array a
    p[1] = 99;
    

Example Assigning an Array to a Pointer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;

int main() {
    const int SIZE = 5;
    int a[] = { 10, 20, 30, 40, 50 };
    int *p = a;
    p[1] = 99;

    for (int i = 0; i < SIZE; i++) {
        cout << p[i] << " ";
    }
    cout << endl;

    return 0;
}

Pointer Arithmetic (Optional)

  • Pointers into arrays support pointer arithmetic
  • We may add an integer offset to a pointer to point to another array location
  • As an example, if p points to the beginning of an array
    int a[] = { 10, 20, 30, 42, 50 };
    int *p = a;
    
  • Then the expression p + 3 is a pointer to the array element with index 3, and
    *(p + 3)
    
    is the array element
  • C++ supports the pointer arithmetic with the operators +, -, ++ and --
  • Since a is actually a constant pointer to the first element of an array, then the following access the same element
    cout << *(a + 3) << endl;
    cout << a[3] << endl;
    
  • This is known as array/pointer duality and explains why array indexes start at zero (0)

Example Showing Array/Pointer Duality

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;

int main() {
    int a[5] = { 10, 20, 30, 42, 50};
    int *p = a;
    cout << *a << endl;
    cout << *(p + 3) << endl;
    cout << *(a + 3) << endl;
    cout << a[3] << endl;
    return 0;
}

Check Yourself

  1. The following code prints ________.
    int a[] = { 2, 3, 4, 5 };
    int *p = a;
    cout << p[3] << endl;
    
  2. The following code prints ________.
    int a[] = { 2, 3, 4, 5 };
    int *p = a + 1;
    cout << *p << endl;
    
  3. The following code prints ________.
    int a[] = { 2, 3, 4, 5 };
    int *p = a;
    p++;
    cout << *p << endl;
    

Exercise 15.1

In this exercise we explore the use of pointers.

Specifications

  1. Copy the following code into a text editor, save it as mypointers.cpp, and then compile and run the starter code to make sure you copied it correctly.
    #include <iostream>
    using namespace std;
    
    int main() {
        // Enter your code here
    
        return 0;
    }
    
  2. Write a declaration for an int variable named num and a variable named numPtr that points to integer values.

    For more information see section 15.1.2: Pointer Declaration and Assignment.

  3. Assign the location of num to the numPtr variable.

    For more information see section 15.1.2: Pointer Declaration and Assignment.

  4. Display the values of both num and numPtr using the following code:
    cout << "num=" << num
         << " numPtr=" << numPtr << endl;
    
  5. Compile and run the your program and verify you see output like the following:
    num=0 numPtr=0x28cc58
    

    The num should be "0" but numPtr value may be any hexadecimal value. For more information see section 15.1.2: Pointer Declaration and Assignment.

  6. Since an address is not that useful, change the output of numPtr to show its dereferenced value.

    For more information see section 15.1.3: The Dereferencing Operator.

  7. After your other code, assign the value of "42" to num. Then copy your cout statement and place it after the assignment operation. Compile and run your program and verify the screen output looks like:
    num=0 numPtr=0
    num=42 numPtr=42
    

Listing of mypointers.cpp

Listing of mypointers.cpp

15.1.6: Summary

Image
A pointer numPtr to variable num

  • We use variables to store data values in a computer's memory
  • Pointer variables (pointers) store memory addresses rather than data values
  • The memory address is where a variable (or other data) is stored
  • Pointers "point" to a variable by telling where the variable is located
  • To declare a pointer, use an asterisk operator
    int *p1 = NULL;
    
  • We may use the "address of" operator (&) to assign addresses to pointers
  • p1 = &v1;
    
  • We also use the asterisk operator to dereference pointers
  • *p1 = 42;
  • We may use the assignment operator = to assign the value of one pointer to another
    p2 = p1;
    
  • Which should not be confused with:
    *p1 = *p3;
    
  • Array variables are really pointer variables
  • An array variable 'points to' the first indexed variable, not the whole array

More Information

Check Yourself

As time permits, be prepared to answer these questions. You can find more information by following the links after the question.

  1. What is a pointer? (15.1.1)
  2. Why do programmers use pointers? (15.1.1)
  3. What is the syntax for declaring a pointer variable? (15.1.2)
  4. What does the "address of" operator return? (15.1.2)
  5. In the following code, what operation does the "*" perform? (15.1.3)
    *p1 = 42;
  6. How do you assign the value of one pointer to another? (15.1.4)
  7. What keyword do you use to create a new dynamic variable? (15.1.5)

15.2: Final Exam Preparation

Learner Outcomes

At the end of the lesson the student will be able to:

  • Discuss how to prepare for the final exam
  • Describe how to take the final exam

15.2.1: About the Final Exam

Important Final Exam Information

Published Schedule: Exam Schedule
Date and Time: Thursday, May 23 @ 1:00pm-3:50pm
Location: regular classroom, everyone at the same time

  • You must attend the exam at the scheduled time or you will receive a score of zero (0)
    • Except by prior arrangement with the instructor for unforeseeable emergency and justifiable reasons
  • Bring a valid ID to the exam
  • Be on time as you can only work on the exam during the scheduled time

15.2.2: How the Final Exam Works

  • The final exam is a Lab Practical
  • This means that you must write code for the exam
  • You will be given a series of programming problems to solve
  • Successfully completing each problem is worth some stated number of points

Administration and Ground Rules

  • I am using Canvas to administer the test
  • The exam is closed books and closed notes
  • However, you may have one 3" x 5" card of notes for the exam
  • Also, you may have blank scratch paper
  • You must use a classroom computer for taking the exam and accessing Canvas
  • You may use both Cygwin and TextPad or NotePad++ to compile and run your code
    • However, your code must compile to receive more than half-credit on the entire exam
    • Partial credit is available if you comment out your problem code
  • You may NOT use the computer to search the Internet
  • You may NOT use any electronic device during the exam except the computer in the classroom
    • Thus, you cannot use your own computer to take the exam
  • You may NOT communicate with anyone but the instructor during the exam

3"x5" Card Requirements

  • Put your name on your card
  • Maximum card or paper size is 3 inches by 5 inches
  • You may use both sides of the card
  • Notes must be handwritten and NOT photocopied
  • No more than three statements in a code sequence on the card — only snippets
  • Any 3" x 5" cards violating these rules will be confiscated before the test
  • You must turn in your 3" x 5" card after the exam

15.2.3: What the Final Exam Covers

  • The final exam is cumulative -- you should know everything we have covered
  • However, the focus is writing code for what we have learned
  • Prior exam topics are listed here:
  • See below for newer exam topics

Code You Should be Capable of Writing

  1. Declaring class types (9.2.2, 10.1.1)
  2. Declaring and defining member and non-member functions (9.2.4, 12.3.4)
  3. Coding constructors with and without parameters (9.2.5, 9.3.1, 9.3.2)
  4. Constructing objects and calling their functions (9.2.3, 9.3.3)
  5. Modifying (changing) values in an object (9.3.4)
  6. Writing set and get functions of classes (9.3.4)
  7. Defining and initializing vectors (10.2.2)
  8. Accessing vector elements (10.2.3)
  9. Finding and changing the size of a vector (10.2.4)
  10. Coding vector parameters and return values (10.2.5)
  11. Processing vectors using loops, including vectors of objects (10.2.4, 10.4.2)
  12. Coding common vector algorithms such as searching for, inserting and deleting elements (10.3.2, 10.3.3, 10.3.4)
  13. Opening a file stream for reading or writing (11.2.5)
  14. Reading different types of data from a file (11.2.5, 12.1.3, 12.1.4)
  15. Loading data from a file and saving it in variables, vectors and objects (11.2.5, 12.1.2-5, 12.3.5)
  16. Writing data from a vector and saving it in a file (12.1.6, 12.3.6)
  17. Developing recursive functions (14.2, Exercise 14.2)
  18. Coding pointers (15.1)

15.2.4: Study Recommendations

  • Study over several sessions instead of one cram session
  • Review your homework assignments and solutions
  • Review the instructor's posted solutions to assignments:
    • Solutions are posted in Canvas
    • Understand how the instructor solved each problem
  • Work through the Practice Final questions in Canvas:
    • Work the problems in groups if it helps you
    • Get explanations for anything you do not understand

    Tip: Complete the entire practice exam.

Final Preparation Tips

  • Make notes on problems on the Practice Final that you had difficulty with
  • Make sure you know how to solve those types of problems
  • Review your notes and prepare your 3" x 5" card
  • Do a quick review just before bed to let your subconscious aid in long term memory.
  • Get plenty of rest before the exam

15.2.5: Exam Taking Tips

  • Arrive at the examination room a little ahead of time.
  • Listen carefully to any oral instructions for taking the exam and read instructions carefully.
  • Read every word in each test question
  • Note that you do not need to comment code for the final exam
    • Unless specifically instructed to in the exam question
  • Use the full time allowed

15.2.6: Review Materials, Questions and Answers

15.3: Sampler Demonstration

Learner Outcomes

At the end of the lesson the student will be able to:

  • Present their sampler assignment

15.3.1: Sampler Presentation

  • Here are the steps for an effective project presentation

Before the Presentation

  • Submit the following to Canvas before the presentation:
    1. README.txt file with project report
    2. All source code (i.e. .cpp files)
    3. Any other files needed to make your program function.
  • Remember that there are no late submittals accepted for the project
  • If you have problems completing the project, then turn in what you have on time and come to class
  • Bring a paper copy of your written report and give it to the instructor at the start of class
    • If you are using your paper for your presentation, be sure to bring an extra copy!
  • Also, be sure you have a quick way to access your project during class to minimize setup time
    • Flash drive (recommended in case of network problems)
    • Canvas
    • Online service

Project Setup

  • The best time to setup is before class
  • Copy your files to the instructor machine in your own folder on the Desktop
  • Verify your code compiles and your project loads its files
  • If you get stuck or do not know what to do, ask for help

During the Presentation

Present the following information:

  • Introduce yourself and state the purpose of your project
  • Compile your program completely and be sure to include all the warnings:
    g++ -Wall -Wextra -Wpedantic -o programName sourceFile.cpp
    
    • I recommend compiling with TextPad because it includes all the warnings
    • Compiling with CodeBlocks will not provide full credit unless you have a graphics project
  • Demonstrate your project, explaining aspects as you go
    • Include an explanation of all extra-credit features
    • Explain how the extra credit and interesting features work
    • Show the code for recursive functions and to help explain features
  • Limit the presentation to 5 minutes or less

After the Presentation

  • Feel free to leave (or stay) after your presentation
  • You can present to the instructor alone after the other presentations are through
  • Remember to study for the final!

Wrap Up

When class is over, please shut down your computer if it is on
Study for the final!
Last Updated: May 15 2019 @14:38:04