Lecture 13. H.pointer
Lecture 13. H.pointer
Object-Oriented Programming
int x;
4 = 1;
(x + 10) = 6;
cout << ++++++x << endl; // ANSI C++ Ref. Section 5.3.2
cout << x++++++ << endl; // ANSI C++ Ref. Section 5.2.6
int main()
{
int x = 10, y = 20;
short a = 9, b = 99;
cout << "x = " << x << '\t' << "address of x = " << &x << endl;
cout << "y = " << y << '\t' << "address of y = " << &y << endl;
cout << "a = " << a << '\t' << "address of a = " << &a << endl;
cout << "b = " << b << '\t' << "address of b = " << &b << endl;
return 0;
}
int main()
{
int x = 10, y = 20;
cout << endl << "Inside main()" << endl;
cout << "x = " << x << '\t' << "address of x = " << &x << endl;
cout << "y = " << y << '\t' << "address of y = " << &y << endl;
f(x, y);
return 0;
}
Question: Can you see the difference between PBV and PBR?
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.7
Part II
What is a Pointer?
int main() {
int x = 10; int* y = &x; // y now contains the address of x
cout << "x = " << x << '\t' << "address of x = " << &x << endl;
cout << "y = " << y << '\t' << "address of y = " << &y << endl;
return 0;
}
int main()
{
int x = 10, z = 20;
int* y = &x; // y now contains the address of x
cout << "x = " << x << '\t' << "address of x = " << &x << endl;
cout << "z = " << z << '\t' << "address of z = " << &z << endl;
cout << "y = " << y << '\t' << "address of y = " << &y << endl;
Web C++
int main()
{
int x1 = 10, x2 = 20;
int *p1 = &x1; // p1 now points to x1
int *p2 = &x2; // p2 now points to x2
*p1 = 5; // now x1 = 5
*p2 += 1000; // now x2 = 1020
*p1 = *p2; // now *p1 = *p2 = x1 = x2 = 1020, but p1 != p2
p1 = p2; // now p1 and p2 both point to x2
cout << "x1 = " << x1 << '\t' << "&x1 = " << &x1 << endl;
cout << "x2 = " << x2 << '\t' << "&x2 = " << &x2 << endl;
cout << "p1 = " << p1 << '\t' << "*p1 = " << *p1 << endl;
cout << "p2 = " << p2 << '\t' << "*p2 = " << *p2 << endl;
return 0;
}
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.13
Example: Pointer and sizeof( )
#include <iostream> /* File: pointer-sizeof.cpp */
using namespace std;
int main()
{
char c = 'A'; char* pc = &c;
short s = 5; short* ps = &s;
int i = 10; int* pi = &i;
double d = 5.6; double* pd = &d;
cout << sizeof(pc) << '\t' << sizeof(*pc) << '\t' << sizeof(&pc)
<< endl;
cout << sizeof(ps) << '\t' << sizeof(*ps) << '\t' << sizeof(&ps)
<< endl;
cout << sizeof(pi) << '\t' << sizeof(*pi) << '\t' << sizeof(&pi)
<< endl;
cout << sizeof(pd) << '\t' << sizeof(*pd) << '\t' << sizeof(&pd)
<< endl;
return 0;
}
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.14
What can a Pointer Point to?
int main()
{
int x = 16;
int* xp = &x; // xp --> x
int** xpp = &xp; // xpp --> xp --> x
int*** xppp = &xpp; // xppp --> xpp --> xp --> x
cout << "x address = " << &x << " x = " << x << endl;
cout << "xp address = " << &xp << " xp = " << xp
<< " *xp = " << *xp << endl;
cout << "xpp address = " << &xpp << " xpp = " << xpp
<< " *xpp = " << *xpp << " **xpp = " << **xpp << endl;
cout << "xppp address = " << &xppp << " xppp = " << xppp
<< " *xppp = " << *xppp << " **xppp = " << **xppp
<< " ***xppp = " << ***xppp << endl;
return 0;
}
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.16
Variable, Reference Variable, Pointer Variable
#include <iostream> /* File: confusion.cpp */
using namespace std;
void xprint()
{
cout << hex << endl; // Print numbers in hexadecimal format
cout << "x = " << x << "\t\tx address = " << &x << endl;
cout << "xref = " << xref << "\t\txref address = " << &xref << endl;
cout << "xptr = " << xptr << "\txptr address = " << &xptr << endl;
cout << "*xptr = " << *xptr << endl;
}
int main()
{
x += 1; xprint();
xref += 1; xprint();
xptr = &xref; xprint(); // Now xptr points to xref
return 0;
}
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.17
const Pointer
cout << "x = " << x << "\t*x = " << *x << endl;
cout << "y = " << y << "\t*y = " << *y << endl << endl;
}
int main()
{
int a = 10, b = 20;
cout << "a = " << a << "\t\t\t&a = " << &a << endl;
cout << "b = " << b << "\t\t\t&b = " << &b << endl << endl;
swap(&a, &b);
cout << "a = " << a << "\t\t\tb = " << b << endl;
return 0;
}
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.23
Common Uses of Pointer
Pointer to Structure
print_distance(&a, &b);
print_distance(&b, &c);
print_distance(&c, &a);
return 0;
}
/* g++ -o point-test point-test.cpp point-distance.cpp */
int main()
{
Student_Record sr[] = {
{ "Adam", 12000, 'M', CSE, { 2006 , 1 , 10 } },
{ "Bob", 11000, 'M', MATH, { 2005 , 9 , 1 } },
{ "Cathy", 10000, 'F', ECE, { 2006 , 8 , 20 } } };
sort_3SR_by_id(sr);
for (int j = 0; j < sizeof(sr)/sizeof(Student_Record); j++)
print_student_record(&sr[j]);
return 0;
}
/* g++ -o sort-sr sort-student-record.cpp student-record-functions.cpp
student-record-swap.cpp */
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.29
Example: student-record-swap.cpp Again
/* File: student-record-extern.h */
Dynamic Memory/Objects
Allocation and Deallocation
int main()
{
int x = 5; // Local int variable
char s[16] = "hkust"; // Local char array
return 0;
}
program codes
(global)
static data
stack
heap
int main()
{
int* ip = create_and_init(10);
cout << *ip << endl;
return 0;
}
memory leak
new int
int main()
{
Date a = { 2006 , 1 , 10 }; Date b = { 2005 , 9 , 1 };
swap(a, b); return 0;
}
head nullptr
’m’ ’e’ ’t’
head nullptr
’m’ ’e’ ’t’
The first and the last node of a linked list always need special
attention.
For the last node, its next pointer is set to nullptr to tell that
it is the end of the linked list.
We need a pointer variable, usually called head to point to the
first node.
Once you get the head of the linked list, you get the whole list!
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.51
Basic Operations of a Linked List
/* To create a node */
ll_node* p = new ll_node;
/* To delete a node */
delete p; // Dangling pointer
p = nullptr; // Reset the pointer for safety reason
// Clean up
delete mp; delete ep; delete tp; return 0;
}
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.53
Common Operations on a Linked List
Common operations:
Create a new linked list.
Search data in the list.
Delete a node in the list.
Insert a new node in the list.
For all these operations, again special attention is usually
needed when the operation involves the first or the last node.
struct ll_cnode
{
char data; // Contains useful information
ll_cnode* next; // The link to the next node
};
return head; // The WHOLE linked list can be accessed from the head
}
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.56
Example: LL-String — ll length.cpp, ll print.cpp
return nullptr;
}
head nullptr
’m’ ’e’ ’t’
1 new_cnode ’a’ 3
head nullptr
’m’ ’e’ ’a’ ’t’
prev current
1
3
head nullptr
’m’ ’e’ ’a’ ’t’
head nullptr
’m’ ’a’ ’t’
ll_delete_all(ll_string);
return 0;
}
root
10
8 15
5 9 12 17
// Function declarations
btree_node* create_btree_node(int data);
void delete_btree(btree_node*& tree) ;
void print_btree(const btree_node* tree, int depth = 0);
int main()
{
btree_node* root = create_btree_node(10); // Create root node
Array as a Pointer
xp + N == &x + sizeof(<type>) × N.
xp - N == &x - sizeof(<type>) × N.
int main()
{
double x = 2.3; // double is 8-byte
double* xp = &x; // xp points to x
cout << &x << endl << xp + 2 << endl << xp - 2 << endl;
head nullptr
’m’ ’e’ ’t’
int main()
{
int x[] = { 11, 22, 33, 44 };
int* y = x; // Both y and x point to the 1st element of array
int* x delete [ ] x
int main()
{
void print_distance(const Point*, const Point*);
int num_points;
cout << "Enter the number of points : "; cin >> num_points;
Point* point = new Point [num_points]; // Dynamic array of points
int main()
{
const int MAX_LINE_LEN = 255;
char s[MAX_LINE_LEN+1];
while (cin.getline(s, MAX_LINE_LEN+1, '\n'))
cout << boolalpha << palindrome(s, s+strlen(s)-1) << endl;
return 0;
}
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.85
Final Remark on C-string literals
int main()
{
const char* s1 = "creative"; // Correct way!
char* s2 = "smart"; // Error if g++ -pedantic-errors
int** x;
x
x[0] x[0][0] x[0][1] x[0][2] x[0][3]
int main()
{
int num_rows, num_columns;
cout << "Enter #rows followed by #columns: ";
cin >> num_rows >> num_columns;
int** matrix = create_matrix(num_rows, num_columns);
int main()
{
// Dynamically create an array with 3 rows, 4 columns
int** x = new int* [3]; // STEP 1
for (int j = 0; j < 3; j++) // STEP 2
x[j] = new int [4];
x &x[0] &x[0][0]
0x14ea5010 0x14ea5010 0x14ea5030
Further Reading:
Array of Pointers to Structures
"Adam"
12000
MALE
CSE
2006
Student_Record* srp[3];
JAN
10
&sr[0] "Bob"
11000
MALE
&sr[1] MATH
2005
SEP
&sr[2] 1
"Cathy"
10000
FEMALE
ECE
2006
SEP
20
int main()
{
Student_Record sr[] = {
{ "Adam", 12000, 'M', CSE, { 2006 , 1 , 10 } },
{ "Bob", 11000, 'M', MATH, { 2005 , 9 , 1 } },
{ "Cathy", 10000, 'F', ECE, { 2006 , 8 , 20 } } };
sort_3SR_by_id(sr);
for (int j = 0; j < sizeof(sr)/sizeof(Student_Record); j++)
print_student_record(&sr[j]);
return 0;
}
/* g++ -o sort-sr sort-student-record.cpp student-record-functions.cpp
student-record-swap.cpp */
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.97
Advantage of Indirect Addressing
During a sorting procedure, in general, many array items are
swapped.
When 2 items are swapped, 3 copy actions are required.
When the array items are big — say, 1MB — objects, the
copying actions may take substantial amount of computation
and time.
A common solution is to make use of indirect addressing and
to sort using the pointers to the objects instead.
The size of pointers is fixed, independent of the objects they
point to. For a 32-bit CPU, it is 4 bytes; for a 64-bit CPU, it
is 8 bytes.
When 2 items are sorted and swapped by their pointers, the 3
copy actions involve only copying 4-byte pointers (for 32-bit
CPU and 8-byte pointers for 64-bit CPU) which are
independent of the size of items they point to.
{horner, kccecia, lixin}@cse.ust.hk COMP2011 (Spring 2018) p.98
Example: Sort by Pointers to Struct Objects
#include "student-record.h" /* File: sort-student-record-ptr.cpp */
void swap_SR_ptr(Student_Record*&, Student_Record*&);
void print_student_record(const Student_Record*);
int main()
{
Student_Record sr[] = {
{ "Adam", 12000, 'M', CSE, { 2006 , 1 , 10 } },
{ "Bob", 11000, 'M', MATH, { 2005 , 9 , 1 } },
{ "Cathy", 10000, 'F', ECE, { 2009 , 6 , 20 } } };
int main()
{
Student_Record sr[] = {
{ "Adam", 12000, 'M', CSE, { 2006 , 1 , 10 } },
{ "Bob", 11000, 'M', MATH, { 2005 , 9 , 1 } },
{ "Cathy", 10000, 'F', ECE, { 2009 , 6 , 20 } } };