C++ Lab 2 - Pointers, References, Strings
Download the example programs from this page or
copy them from the course home page to your
directory for this lab as follows (assuming you are currently in
the directory):
cp ~cpsc/public_html/Spring2010/CPSC270A/lab2/*.cc .
References and Pointers
Recall that in Java when you declare a
variable to be some object type then the variable is actually a
reference to the object, that is, it contains the address of the
object rather than the object itself. So for example, if you have a
Node class, then
the declaration
Node myNode;
would declare myNode to be a reference (currently null) to a Node
object. The actual object would be created using the new operator.
In C++, the above declaration would create the actual Node (no
new would be needed).
To declare a reference (pointer) to an object we use *.
The following declaration declares myNodePtr as a pointer to a Node:
Node * myNodePtr;
The actual node would be constructed using the new operator as follows:
myNodePtr = new Node;
You can also use * and new on primitive data types such as int. The
following allocates space in memory for an int and assigns intPtr
to point to it.
int * intPtr = new int;
To access the actual value of the integer you need to
use the operator * to dereference the pointer -
*intPtr is the value of the integer in the location pointed
to by intPtr.
The & operator gives the address of a variable. Some examples using
* and &:
myNodePtr = &myNode;
int * numPtr = new int;
int num = 5;
cout << &num << " an address!"; //prints the address of num
*numPtr = 13; // *numPtr is the contents of the location pointed
// to by numPtr - * is "dereferencing" numPtr
The program PointerFun.cc illustrates
some of the properties of the & ("address of") operator and the
* operator (when used to declare and when used to dereference a
pointer variable). Study it then compile and run it.
Dynamic Arrays
To create arrays dynamically at runtime you need to use a pointer and
new to allocate the space needed. The following declares a to be a
pointer and allocates space in memory for n ints.
int * a = new int[n];
The program DynamicArray.cc illustrate this.
Try it.
Problems with memory when using dynamic allocation:
In C++ space allocated remains allocated
to your process unless you explicitly free it. There is no automatic
garbage collection as there is in Java. The delete command
is used to place the memory allocated to a pointer back on free store.
delete numPtr; // returns the space for the int pointed to by numPtr
delete [] a; // frees the space for the array pointed to by a
The program ArrayMemory.cc illustrates the
problem with allocating lots of space without freeing it.
Follow the instructions below to run the program, examining memory
as it runs. The program pauses for input so
you can see how much memory is being used.
Parameter Passing
The default mode of parameter passing in
C++, as in Java, is pass by value. Parameters passed this way are
not changed by the function (method). But in Java, because the
"value" of an object variable is a reference, the reference isn't
changed but the object it refers to can be changed. An array
in C++ is actually a pointer to the first element in the array.
Thus, in the double every other element example you were able
to change the actual array.
To pass a parameter by reference in C++ you use the ampersand in
the header for the function. So, the following would pass the first
two parameters by reference and the third one by value:
void doStuff (int& a, int& b, int c)
{
c = c * 2;
a = a + c;
b = b - c;
}
A call to the function would just use the int variables for the
actual parameters - the address of the first two would be passed.
For example,
int m = 150;
int n = 100;
int p = 5;
doStuff(m,n,p);
Note: It is standard practice to just list the type of each parameter
in the declaration (when it is separate from the definition) -
in this example you would put
void doStuff (int&, int&, int)
This code is in ReferenceParameters.cc.
Run it to make sure you understand what happens and how reference and value
parameters differ.
Strings in C++
A string in C++ is an array of characters (type char)
that has the null character (escape sequence \0) at the end.
The null character is automatically added to the characters in
a string when the string is read in or is assigned as a literal.
The program StringBasics.cc
gives an example. This program uses two functions provided by
C++ - the sizeof function can be applied to any variable
to find out how much space (number of bytes) the variable occupies.
The function strlen is a function in the standard library
that gives the number of characters in the string.
The program also uses the function strcpy to copy
one string to another. Note that the first argument is the
destination, the second is the string to be copied. This function (or
a loop where you copy character by character) should be used
when you need to copy. You cannot use assignment.
Compile and run the program. Note that for the string literal the
number of bytes is one more than the number of characters - that
accounts for the null character. For the string you typed in,
the number of bytes is the number declared for the array.
Exercise:
- See what happens when you try assigning strings.
There is already a declaration for string3 in the program.
Add an assignment statement to assign string3 to be the same as
string1. Try compiling and see what the error message is.
- Now change your assignment to assign string3 to be the same as
string2. Try compiling. This is a more general error message that
applies to any type of array in C++.
- Now try assigning string3 to be a literal. What happens?
- Use strcpy to assign string3 to be a literal. Does it
work?
Reading in Strings
If you didn't already do it run the program above again entering
a string with more than one word. Do it again putting several
white space characters in front of the sentence. What happened?
You should have noticed that cin skips over whitespace and
stops reading at whitespace. So it doesn't work to read a whole line
that may contain spaces. To do that you need to use one of the
functions get or getline that operate on cin.
The program ReadStrings.cc reads in
two lines of text and prints them. Note the alternate syntax
for using get and getline.
Exercise:
- Study the code then compile and run the program.
- Comment out the line that adds the null character. Run the
program at least twice:
- Enter a shorter string for the second input than the first.
What happened?
- Enter a longer string for the second but less than
the maximum length. What happened?
The point - if you create your own string character by character
you must explicitly add the null character to the end.
Char
Variables and literals of type char can be manipulated just as in
Java. Casting to an int gives the ASCII code and casting an
int to char gives the character. The
program Frequency.cc reads
in a string character by character and determines the frequency
of each letter in the alphabet. Study the code to be sure you
understand it. Compile and run.
The string class
To use the C++ library string you need to
add the INCLUDE preprocessor directive. The class is in
the std namespace as is iostream so you do not need
an additional using statement. Some of the functions provided in
the library are length, find, substr,
replace, and insert. The example program
StringClass.cc uses some of these. Run
it to see how it works. In particular, figure out the following:
- The substr function is not the same as Java's substring
method. What does the second argument to substr represent?
How does this differ from Java?
- What happens if you request a substring starting at an index
that is out of bounds?
- What happens if you request a substring starting at an index
that is in bounds but you request more characters than are in
the string from that index to the end?
Homework - Due, Wednesday, February 3
- Write a C++ program that implements the string-matching
algorithm referred to in problem #3 on page 24. Use a function
that is called from main for your algorithm. In particular
your program should take in a line of text and another string
(which may contain spaces). It should return the index of the
first character in the string if the string is found in the
text or -1 if the string is not in the text. Note: You only need
to find the first instance of the string in the case that it appears
more than once.
- Write a C++ program that implements an anagram checking algorithm
(problem #10 on page 39). You may assume the two strings have no
whitespace.