Chapter Seven: Pointers and Structures: Big C++ by Cay Horstmann
Chapter Seven: Pointers and Structures: Big C++ by Cay Horstmann
Structures
… balance += depositAmount …
… balance -= withdrawalAmount …
But not all deposits and withdrawals should be from the same bank.
By using a pointer,
it is possible to switch to a different account
without modifying the code for
deposits and withdrawals.
double harrys_account = 0;
20266
20274
20292
harrys_account 0 20300
20308
20316
20324
20332
20340
20348
Big C++ by Cay Horstmann
Copyright © 2018 by John Wiley & Sons. All rights reserved
Pointer Initialization
double harrys_account = 0;
double* account_pointer = & harrys_account;
20266
20274
20292
harrys_account 0 20300
20308
20316
20324
20332
account_pointer 20300 20340
20348
Big C++ by Cay Horstmann
Copyright © 2018 by John Wiley & Sons. All rights reserved
Addresses and Pointers
Harry wanted to use his account, but he found the balance was zero:
double harrys_account = 0;
account_pointer = &harrys_account; //Picture #1
double joint_account = 1000;
To access his joint account hoping it still has a non-zero
balance, Harry would change the pointer:
account_pointer = &joint_account; //Picture #2
not arrows.
// withdraw $100
*account_pointer = *account_pointer - 100;
// deposit $1000
*account_pointer = *account_pointer + 1000;
If you don't already know what the pointer will point to, initialize it with
nullptr:
double* account_pointer = nullptr;
// Withdraw $100
*account_pointer = *account_pointer - 100;
// Print balance
cout << "Balance: " << *account_pointer << endl;
// Withdraw $100
*account_pointer = *account_pointer - 100;
return 0;
}
int a = 15;
int* p = &a;
int* q = &a;
cout << *p + *q << endl; _________________
int a = 15;
int* p = &a;
cout << *p << " " << p << endl; ______________
Big C++ by Cay Horstmann
Copyright © 2018 by John Wiley & Sons. All rights reserved
Common Error: Confusing Data And Pointers: Where’s the *?
int a[10];
double* p = a;
// Now p points to a[0]
Big C++ by Cay Horstmann
Copyright © 2018 by John Wiley & Sons. All rights reserved
Pointer Arithmetic, and Array/Pointer Duality
but
double sum(double a[], int size)
looks a lot more like we are passing an array.
You can solve this problem by passing an array to hold the answer:
void firstlast(const double values[], int size,
double result[])
{
result[0] = values[0];
result[1] = values[size - 1];
}
An alternative fix is to dynamically allocate the result[] array in
the function using the new keyword, but we’ll save that for later in
the chapter.
Big C++ by Cay Horstmann
Copyright © 2018 by John Wiley & Sons. All rights reserved
Program Clearly, Not Cleverly
A constant pointer:
const double* p = &balance;
cannot modify the value to which p points.
*p = 0; // Error
Of course, you can read the value:
cout << *p; // OK
The function can use the pointer values to read the array elements, but
it cannot modify them.
C strings
• Are arrays of type char
• Provide a more primitive level of string handling.
• Are from the C language (C++ was built from C).
For example:
// An array of 6 characters
char c[] = "Harry";
The toupper function is defined in the <cctype> header. It converts a lowercase char
to uppercase. The tolower function does the opposite.
You can write a function that will return the uppercase version of a C++ string:
/**
Makes an uppercase version of a string.
@param str a string
@return a string with the characters in str converted to uppercase
*/
string uppercase(string str)
{
string result = str; // Make a copy of str
for (int i = 0; i < result.length(); i++)
{
// Convert each character to uppercase
result[i] = toupper(result[i]);
}
return result;
}
Big C++ by Cay Horstmann
Copyright © 2008 by John Wiley & Sons. All rights reserved
C String Functions from the <cstring> Library: Table 4
You may not know beforehand how many values you need in an
array.
delete account_pointer;
delete[] account_array;
delete[] account_array;
account_array[0] = 1000;
// NO! You no longer own the
// memory of account_array
int* pointer_array[10];
int* counts[10];
for (int i = 0; i < 10; i++)
{
counts[i] = new int[i + 1];
} Big C++ by Cay Horstmann
Copyright © 2008 by John Wiley & Sons. All rights reserved
A Galton Board Simulation: Printing Rows
We will need to print each row:
counts
if i is 4
int r = rand() % 2;
// If r is even, move down,
// otherwise to the right
if (r == 1)
{
j++;
}
counts[i][j]++;
Big C++ by Cay Horstmann
Copyright © 2008 by John Wiley & Sons. All rights reserved
A Galton Board Simulation: Complete Code Part 1
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(time(0));
int* counts[10];
return 0;
}
Big C++ by Cay Horstmann
Copyright © 2008 by John Wiley & Sons. All rights reserved
A Galton Board Simulation: Results
This is the output from a run of the program, with each number
being a count of the balls that hit that peg in the triangle.
1000
480 520
241 500 259
124 345 411 120
68 232 365 271 64
32 164 283 329 161 31
16 88 229 303 254 88 22
9 47 147 277 273 190 44 13
5 24 103 203 288 228 113 33 3
1 18 64 149 239 265 186 61 15 2
Big C++ by Cay Horstmann
Copyright © 2008 by John Wiley & Sons. All rights reserved
Topic 6
Use the = operator to assign one structure value to another. All members
are assigned simultaneously.
StreetAddress dest;
dest = white_house;
is equivalent to
dest.house_number = white_house.house_number;
dest.street_name = white_house.street_name;
struct StreetAddress
{
int house_number;
string street_name;
};
StreetAddress make_random_address()
{
StreetAddress result;
result.house_number = 100 + rand() % 100;
result.street_name = "Main Street";
return result;
}
You can also access a structure value in its entirety, like this:
StreetAddress start = delivery_route[0];
Instead, you must first apply the * operator, then the dot:
(*address_pointer).house_number = 1600; // OK
Employee harry;
harry.name = "Smith, Harry";
harry.office = &accounting;
Employee sally;
sally.name = "Lee, Sally";
sally.office = &accounting;
Big C++ by Cay Horstmann
Copyright © 2018 by John Wiley & Sons. All rights reserved
Structures and Pointers: Complete Code Example, Part 1
// sec08/streets2.cpp
#include <iostream>
#include <string>
using namespace std;
struct StreetAddress
{
int house_number;
string street_name;
};
struct Employee
{
string name;
StreetAddress* office;
};
void print_address(StreetAddress address)
{
cout << address.house_number << " " << address.street_name;
}
Big C++ by Cay Horstmann
Copyright © 2018 by John Wiley & Sons. All rights reserved
Structures and Pointers: Complete Code Example, Part 2
void print_employee(Employee e)
{
cout << e.name << " working at ";
print_address(*e.office);
}
int main()
{
cout << "A dynamically allocated structure" << endl;
StreetAddress* address_pointer = new StreetAddress;
address_pointer->house_number = 1600;
address_pointer->street_name = "Pennsylvania Avenue";
print_address(*address_pointer);
delete address_pointer;
cout << endl << "Two employees in the same office" << endl;
StreetAddress accounting;
accounting.house_number = 1729;
accounting.street_name = "Park Avenue";
Employee sally;
sally.name = "Lee, Sally";
sally.office = &accounting;
Employee sally;
sally.name = "Lee, Sally";
sally.office = accounting;
Now the StreetAddress structure for the accounting office has two
shared pointers pointing to it: accounting and sally.office. When
both of these variables go away, then the structure memory is
automatically deleted.