Week 3 Lecture Summary for CSC 309
These notes are not intended to be complete. They serve as an outline to the class and as a supplement to the text.
Pointers
- A pointer is a number used to locate an object or variable.
- Recall the use of object in this context means any region in memory that has a type
- A pointer variable is a variable that holds the address of an object or another variable.
- Can use the pointer to indirectly access the object or the value stored in another variable
- We can declare a pointer variable by using the
'*'
operator. - The above statement reads.. declare
pCount
to be a pointer to an integer and assign to the pointerpCount
the address '&' of variablecount
. - The use of
*
in*pCount
declares thatpCount
is a pointer variable. - The use of
&
in&count
is the address-of operator. The address-of operator returns the address of a variable. - We can use the dereferencing operator
*
on the pointer to return the value that the pointer points to.
Example
int count = 5; int *pCount = &count;
cout << *pCount; // outputs 5 *pCount = 12; cout << *pCount; // outputs 12 cout << count; // outputs 12
Declaring and Assigning Pointers
- The * symbol may be separated from its identifier by one or more spaces or placed right after the data type. This leniency can lead to confusing code.
- Make sure a pointer is initialized before you use it.
- If you are not certain initialize the pointer to NULL or 0.
NULL
is a preprocessor variable found in header filecstdlib
defined to be 0.- A pointer cannot contain an integer value only an address of an object or variable. Zero is an exception, it implies that the pointer points nowhere.
- Cannot dereference a pointer containing 0 or NULL.
- Dangerous to deference an unitialized pointer. Typically this will cause the program to crash during run-time.
- Cannot assign to a pointer a non pointer variable.
- A collection of variables of the same type under a single name.
- The elements of the array occupy contiguous memory cells. For example if the first element of the array is at memory location A, the next element occupies memory location B.
- Arrays can be static or dynamically allocated. For now we deal with static.
- Arrays in C++ are not Objects, unlike Java.
- Arrays, unlike a vector, are fixed in length (Dimension).
- The length needs to be known at compile time, therefore the length cannot be a non-constant variable.
- Can use the index-operator
[ ]
- The elements of an array are indexed starting with 0.
- Using pointers and pointer arithmetic. The name of an array is a pointer to the first element.
- C++ does not perform bounds checking on arrays.
- Can pass an array to a function. Use the name of the array.
- The called function needs to know the size of the array. Typically the size is passed in to the function as an argument.
- When passing in an array you are passing the address of the first cell, not a copy.
- Two ways to declare the array parameter.
- Can use [ ] operator or * operator in either one to access the values stored in the array.
- Can use the const keyword in the function parameter. This ensures that the function cannot alter the values in the array.
- When calling the function pass the name of the array not an individual cell.
- Consider an example of reversing the order of an array.
- See reverse.cpp
- An array of chararacters, with the null character ('\0') at the end.
- The name of the array is a pointer to the first element.
char *
- The input and output operators have been overloaded to operate on C-Strings.
- Same as arrays.
- Do not need to pass length. Can stop when '\0' is encountered or use
strlen
function. #include <cstring>
- Make sure the pointer being passed to these functions is nonzero.
- See this weeks examples on using some of these functions.
- Declaring an array using the [ ] notation, creates a pointer constant.
int* pCounter, pRank, pJamas;
There is no such thing as an int*
type, the compiler will only define pCounter
as a pointer variable.
The other variables pRank
and pJamas
are defined as ordinary integer variables.
Example
int count = 9; int *pCount = count; // won't compile int index = 0; int *pIndex = index; // won't compile int *pjs = 0; // compiles and executes cout << *pjs; // compiles, run time error. int *pTimes = 3; // won't compile, can only assign 0
Arrays
Defining and Initializing Arrays
const unsigned int LENGTH = 10; int numbers [LENGTH]; // ok; creates an array of integers of length 10 unsigned int cap = 5; int five[cap]; // error: cap not a constant. This compiled in Bloodshed int scores [LENGTH] = {4,3,2,1,0}; // ok int counters [] = {0,1,2,3,4}; // ok int a1[5] = {-1}; // ok, a1[0] is -1, all other cells 0
Accessing Array Elements
scores[0]; // returns 4 *scores; // returns 4 scores[1] == *(scores + 1); *scores + 1; // returns 5 *(scores + 1) // returns 3 *scores + 1 != *(scores + 1); // * has higher precedence than + scores[0] + 1 != scores[1];
scores[10] = 20; // will compile but illegal, // anything can happen during the run of the program.
Passing Arrays to Functions
void print(int scores[], int size); void print(int *scores, int size);
void print(const int scores[], int size); void print(const int *scores, int size);
print(scores, 5); // ok print(scores[0], 5); // won't compile
C-Style Strings
Defining and Initializing
char word1 [] = "hello"; // c-string, word1[5] is '\0' cout << word1; // outputs hello char word2[] = {'h','l','l'}; // Not a string. No '\0' char word3 [5]; cin >> word3; // skips leading whitespaces. // keeps reading until a whitespace is encountered // puts the null-terminator at the end of the array // >> will overflow the buffer. char greeting [] = "hello class" // spaces between words are allowed.
Passing C-Strings to Functions
int main() { char s1[20] = "CD-ROM."; int h1 = countHyphens1(s1); int h2 = countHyphens2(s1); ... } int countHyphens1(char s[]) { int count = 0; for (int i = 0; s[i] != '\0'; i++){ if (s[i] == '-') count++; } return count; } int countHyphens2(char *s) { int count = 0; for(; *s != '\0'; s++){ if (*s == '-') count++; } return count; }
C-Style Library String Functions
Constant Pointer vs Pointer to a Constant
int count = 5; const int *pCount = &count; cout << *pCount; // outputs 5 *pCount = 20; // won't work.
pCount
is a pointer to a constant integer. This implies the value to which it points cannot be changed by the pointer.
int count = 5; int *const pCount = &count; *pCount = 20; // works. int index = 10; pCount = &index; // won't work
pCount
is a constant pointer to an integer. This implies the pointer cannot change, it is always pointing to count
int a1 [] = {1,2,3,4,5}; int a2 [5]; a2 = a1; // error, a2 is a constant pointer. // this compiled in bloodshed 4.9.9.2 and ran // but the assignment did not hold. int *a3; a3 = a1; // okay, because a3 is a pointer int * const a4; a4 = a1; // error a4 is a constant pointer