Pointers Pointers are a unique class of variables whose purpose is to “point” to other variables Pointers allow programmers direct access to memory addresses to variables used in the program Great! So?
Motivation for Pointers 1.Essential in dynamic data environments –So far, we have only seen static data (i.e. we know exactly how many variables we need). –Think of arrays and how inconvenient it is to always have to know the size beforehand!
Motivation for Pointers (2) 2.No pointers, no data structures. –Pointers are used to build complex data structures such as: Arrays, Trees, Lists, Stacks, Queues, Rings, etc. 3.C++ cannot pass a physical block of memory as argument into a function. –Rather, pass a variable that “points” to the first element in the structure.
How Does a Pointer “Point?” Pointer variables hold memory addresses. Because of this, a pointer can be used to wander into a machine’s memory space. This ability is often hailed as pointers’ greatest advantage and disadvantage. –Good because of speed and flexibility –Bad because of out-of-bounds memory accesses
How Does a Pointer “Point?” (2) Keep in mind that pointers “point” by holding the memory address of the element to which it is pointing. To obtain the memory address of a variable, we use the address operator &. For example: int x = 10; cout << “The value of x is “ << x << endl; cout << “The address of x is: “ << &x << endl; You would see something similar to: The value of x is 10 The address of x is 0x815acc3f
Declaring Pointers Because the different types of variables take different amounts of memory ( double takes more than float ), we declare a pointer as a specific data type. In general we declare with the following syntax: data-type *pointer-name;
Declaring Pointers (2) An example pointer declaration: int *numAddr;// numAddr points to a // variable of type int A good way to understand declarations is to read them backwards: “numAddr points to an integer”
Simple Example Again, pointers are variables whose value is an address of a location in memory. int num = 6; int *numAddr; // numAddr is an integer pointer numAddr = # // numAddr points to num // this is valid because num // is of type int! The variable numAddr holds the address of another variable, num, so it “points” to the variable whose memory address it holds.
Visualizing Pointers int num = 6; int *numAddr; // numAddr is a pointer numAddr = # // numAddr points to num
Dereferencing Pointers A pointer variable’s value is a memory address. So how do we obtain the actual content at the address to which it points? We use the deference operator * to obtain this value Take our previous example of the pointer numAddr. In our programs, to obtain the value of num, we do the following: *numAddr
Dereferencing Pointers (2) In other words *numAddr means the value of the variable whose address is stored in numAddr This procedure is called dereferencing: –The value is obtained by first looking up the address the pointer holds and then going to that location in memory to get the value.
Example Program int main() { int *numAddr; //numAddr points to an int int miles, dist; dist = 158; miles = 22; numAddr = &miles; //Assign an address into numAddr //some number (memory address of variable: miles) cout << “The address in numAddr is “ << numAddr << endl; //dererenced here. We obtain 22 cout << “The value pointed to by numAddr is “ << *numAddr << endl;
Example Program (pt 2) numAddr = &dist;//now numAddr points to dist //another hex number (memory address of variable: dist) cout << “The address in numAddr is “ << numAddr << endl; //158 cout << “The value pointed to by numAddr is “ << *numAddr << endl; return 0; } /* Notice that the deference operator * will return the value of the variable that is pointed to, rather than the address of the variable! */
Reference Variables Like pointers, references hold an address Unlike pointers, their values cannot be altered. (We saw that the numAddr pointer pointed to miles and then later, to dist in our example program) References are normally just used for functions (we have seen the pass-by- reference function calls)
Reference Variables (2) To declare a reference variable, we use the form: data-type &new-name = existing-name; For example: double total = 4.5; double &sum = total; In essence what we have done is given total an alias called sum. Warning: We cannot declare a reference without initializing it (i.e. double ∑ is illegal!)
Reference Variables (3) Again references should have the same data type as the variable we wish to give an additional name. This should be obvious since a reference is essentially the variable under a different name.
Simple Example on References int main() { int miles; int &milesRef = miles; milesRef = 42;//same as saying miles = 42; cout << “I traveled “ << miles << “ miles!\n”; // above is same as saying: // cout << “I traveled “ << milesRef << “ miles!\n”; return 0; }
Comparison of References and Pointers Reference: int b, c; Int &a = b; //address of b automatically assigned a = 10; //a is implicitly dereferenced //a cannot be reassigned another address a = c;//illegal! Pointer: int b, c; int *a = &b; //address of b manually assigned *a = 10; //a explicitly dereferenced //a can be reassigned another address a = &c; //a now points to c