310 likes | 319 Views
Learn about the five attributes of variables in C++, how memory addresses are assigned to variables, and how to use pointers to access and manipulate variable addresses.
E N D
CS31 Discussion 1HFall18: week 7 TA: BehnamShahbazi bshahbazi@cs.ucla.edu Credit to former TAs: SepidehMazrouee
Pointers • Every variable in C++ can be described by fivedifferent attributes: • int main(void) • { • int bankAccount = 1000324; • ... • } • 1. every variable has a name • 2. every variable has a type • 3. every variable has a size • 4. every variable has a value • 5. every variable has an address! Acknowledgement: Professor Nachenberg – for the slides CS31 - Spring13 - Section1J TA: SepidMaz
stdID grade 1 byte Variable Addresses 00000000 00000001 • Every byte in the computer‘s memory has its own address (just like each house on a street has an address). • When you define a variable in your program, the computer finds an unused set of address in memory and reserves them for your variable. • int main(void) • { • int stdID= 1500234; • char grade= ‘B’; • } … 00001000 00001001 00001002 00001003 00001004 00001005 00001006 00001007 00001008 00001009 00001010 00001011 1500234 66 … 99999990 99999991 99999992 CS31 - Spring13 - Section1J TA: SepidMaz
stdID grade Variable Addresses 00000000 00000001 • Important: The address of a variable is defined to be the first address in memory where the variable is stored. • Questions: • 1. What is stdID’saddress in memory? • 2. What about grade’saddress? • int main(void) • { • int stdID = 1500234; • char grade = ‘B’; • } … 00001000 00001001 00001002 00001003 00001004 00001005 00001006 00001007 00001008 00001009 00001010 00001011 1500234 66 … 99999990 99999991 99999992 CS31 - Spring13 - Section1J TA: Sepid Maz
Finding the Address of a Variable stdID grade • We can get the address of a variable using the &operator. • int main(void) • { • int stdID= 1500234; • char grade= ‘B’; • cout << “Value: “ << stdID<< endl; • cout << “Size: “ << sizeof(stdID) << endl; • cout << “StdID’saddress: “<< &stdID<<endl; • …cout << “grade’s address: “ << &grade; • } • If you place an & before a variable in your program, it means “give me the numerical address of the variable.” 00001000 00001001 00001002 00001003 00001004 00001005 00001006 00001007 00001008 00001009 00001010 00001011 1500234 66 CS31 - Spring13 - Section1J TA: SepidMaz
& is for References and Pointers When we place an & before afunction parameter, we make the parameter a reference parameter. void booboo(int&a) { ... // a is a reference parameter. } When we place an & before a variable in a program statement, we are asking for that variable’s address. int main(void) { int a; cout << &a; // get a’s address ... } Be careful not to confuse the two. CS31 - Spring13 - Section1J TA: Sepid Maz
Every Variable Has An Address n x 12 ... 00001062 ... Question: What is the output for this code? void change_me(int x); int main(void) { int n; cout << "Enter a #: "; cin >> n; cout << n << endl; change_me(n); cout << n << endl; } // definition void change_me(int x) { x = 12; } 3 3 00001070 ... Output: Enter a #: 3 3 3 CS31 - Spring13 - Section1J TA: Sepid Maz
ptr price 300 The Pointer Variable • A pointer variable is a variable that holds an address value rather than a normal int, float, double or string value. • You can set a pointer variable equal to a variable’s address: • int main(void) • { • float price = 300; • Pointer ptr; // a pointer variable • ptr = &price; // ptr gets price’s address • ... • On PCs, pointer variables require 4 bytes of storage. Why? • (depending on the machine- it’s 4 bytes for 32bit system) ... 00001000 00001001 00001002 00001003 00001004 00001005 00001006 00001007 ... 1000 CS31 - Spring13 - Section1J TA: SepidMaz
The sizeof a Pointer Variable A pointer variable needs to be able to point to any addressin the computer’s memory. Let say a 32 bit system that has 4 gigabytes (4 billion bytes) of memory. Therefore, each pointer variable needs to be able to hold values between 0 and 4,000,000,000 (4 billion). In order for a pointer variable to hold values between 0 and 4 billion, it needs 4 bytes of storage (232values). CS31 - Spring13 - Section1J TA: Sepid Maz
Defining a Pointer Variable… int main(void) { float price = 300; Pointerptr; // WRONG!!! Incorrect syntax ptr = &price; // ptr gets price’s address When you define a pointer variable, you must specify what type of variable the pointer will point to… CS31 - Spring13 - Section1J TA: Sepid Maz
How to Define a Pointer Variable… int main(void) { float price = 300; float*ptr; // ptr can point to float variables ptr = &price;// ptr gets price’s address To define a pointer variable, you use the following syntax: Type* pointer_name; e.g. int *anIntPointer, *anotherOne; string *ptr_to_a_string; When you define your variables the * indicates that the variable is a pointer and not a regular variable.
double dip; // dip is a double variable fptr= &dip; // ERROR!fptr can only point to a float variable int stdID, courseNo; // stdIDand courseNoare int variables pToInt = &stdID; // This is just fine… pToInt = &courseNo; // This too… Now pToInt points to courseNo Assigning a Pointer Variable… The type of the pointer variable must match the type of the variable it’s pointing to. main() { float *fptr; ... fptr may only point to float variables. main() { int *pToInt; … pToIntmay only point to integer variables. CS31 - Spring13 - Section1J TA: Sepid Maz
Assigning a Pointer Variable… courseNo stdID ptr 00000000 00000001 int main(void) { int stdID, courseNo; stdID= 70232143; courseNo= 150012; int *ptr; cout << “stdIDis at address “ << &stdID<< endl; ptr = &courseNo; cout << “ptr points to address “ << ptr << endl; ptr = &courseNo; cout << “ptr points to address “ << ptr << endl; } … 00001000 00001001 00001002 00001003 00001004 00001005 00001006 00001007 00001008 00001009 00001010 00001011 70232143 150012 1004 ? … courseNois at address 1004 ptr points to address 1004 CS31 - Spring13 - Section1J TA: SepidMaz
Assigning a Pointer Variable… courseNo stdID ptr stdIDis at address 1000 ptr points to address 1000 int main(void) { int stdID, courseNo; stdID=70232143; courseNo= 150012; int *ptr; cout << “stdIDis at address “ << &stdID<< endl; ptr = &stdID; cout << “ptr points to address “ << ptr << endl; ptr = &courseNo; cout << “ptr points to address “ << ptr << endl; } 00000000 00000001 … 00001000 00001001 00001002 00001003 00001004 00001005 00001006 00001007 00001008 00001009 00001010 00001011 70232143 150012 1000 1004 … CS31 - Spring13 - Section1J TA: Sepid Maz ptr points to address 1004
Pointer Variables are Variables Too! A pointer variable, like a regular variable has the same 5 attributes. 1.name: pfv 2.type: pointer to a float variable 3.size: 4 bytes (= 32bits) 4.value: the value of a pointer variable is the address of another variable. 5.anaddress: Pointer variables have their OWN address too! main() { float fv = 3.14; float *pfv; pfv = &fv; cout << “value: “ << pfv << endl; cout << “size: "<<sizeof(pfv)<<endl; cout << "address: " << &pfv << endl; } CS31 - Spring13 - Section1J TA: Sepid Maz
3.14 fv pfv Pointer Variable Attributes 00000000 00000001 main() { float fv = 3.14; float *pfv; pfv = &fv; cout << “value: “ << pfv << endl; cout << “size: "<<sizeof(pfv)<<endl; cout << "address: " << &pfv << endl; } … 00009240 00009241 00009242 00009243 00009242 00009245 00009246 00009247 00009248 00009249 00009250 00009251 9241 value: 9241 size: 4 … address: 9245 CS31 - Spring13 - Section1J TA: Sepid Maz
c 65 ps s pc 42 9240 9241 Pointer Challenge Question:what is the size of the following variables? 00000000 00000001 main() { char c = ‘A’; short s = 42; char *pc = &c; short *ps = &s; bool *pbool; ... } … 00009240 00009241 00009242 00009243 00009244 00009245 00009246 00009247 00009248 00009249 00009250 00009251 All pointer variables are 4 bytes long, regardless of what type of variable they point to, since they have to hold an address. … CS31 - Spring13 - Section1J TA: Sepid Maz
2 ptr hands *Operator The * operator is used to “de-reference” a pointer. It lets you access what the pointer points to. 00000000 00000001 main() { short hands = 2; short *ptr; ptr = &hands; *ptr = 3; cout << *ptr << endl; cout << hands<< endl; } … 00009240 00009241 00009242 00009243 00009244 00009245 00009246 00009247 00009248 00009249 00009250 3 9240 3 3 “Store a value of 3 where ptr points to.” “Print the value stored where ptr points.” … CS31 - Spring13 - Section1J TA: Sepid Maz
iptr Question: What Happens Here? 00000000 00000001 main() { int *iptr; *iptr = 123456; } … 00009240 00009241 00009242 00009243 00009244 00009245 00009246 00009247 00009248 00009249 00009250 989699 Where does iptr point to? It points randomly in memory! You must always point a pointer variable at another variable before using the * operator on it! 123456 CS31 - Spring13 - Section1J TA: Sepid Maz Operating system??
p2 p1 b a 1 2 Another Example… 00000000 00000001 main() { int a=1, b=2; int *p1, *p2; p1 = &a; p2 = &b; *p1 = *p2; } … 00006420 00006421 00006422 00006423 00006424 00006425 00006426 00006427 00006428 00006429 00006430 00006431 00006432 00006433 00006434 00006435 2 6420 “Get the value pointed to by p2. Store this value in the variable pointed to by p1.” 6424 CS31 - Spring13 - Section1J TA: Sepid Maz …
p2 a b p1 2 2 6420 6424 Another Example… 00000000 00000001 main() { int a=1, b=2; int *p1, *p2; // how to define 2 ptrs p1 = &a; p2 = &b; p1 = p2; } … 00006420 00006421 00006422 00006423 00006424 00006425 00006426 00006427 00006428 00006429 00006430 00006431 00006432 00006433 00006434 00006435 6424 “Store the value of variable p2 into variable p1.” CS31 - Spring13 - Section1J TA: Sepid Maz …
p2 b a p1 2 1 6420 6424 Question: What do you think about this example? 00000000 00000001 main() { int a=1, b=2; int *p1, *p2; // how to define 2 ptrs p1 = &a; p2 = &b; if (*p1 == *p2) { do something; } } … 00006420 00006421 00006422 00006423 00006424 00006425 00006426 00006427 00006428 00006429 00006430 00006431 00006432 00006433 00006434 00006435 “Compare the value pointed to by p1 to the value pointed to by p2.” if (1 == 2) … CS31 - Spring13 - Section1J TA: Sepid Maz …
p2 p1 b a 2 1 6420 6424 Question: How about this? 00000000 00000001 main() { int a=1, b=2; int *p1, *p2; // how to define 2 ptrs p1 = &a; p2 = &b; if (p1 == p2) { do something; } } … 00006420 00006421 00006422 00006423 00006424 00006425 00006426 00006427 00006428 00006429 00006430 00006431 00006432 00006433 00006434 00006435 “Compare the value of variable p1 to the value of variable p2.” if (6420 == 6424) … CS31 - Spring13 - Section1J TA: Sepid Maz …
Using Pointers Instead of References 1 x pa 00000000 00000001 … void set(int*pa) // like a reference! { pa = 5; } main() { int x = 1; set(&x); cout << &x; } 00009240 00009241 00009242 00009243 00009244 00009245 00009246 00009247 00009248 00009249 00009250 5 9240 Store a value of 5 in the variable where pa points (at location 9240). CS31 - Spring13 - Section1J TA: Sepid Maz
Question:what is the output of this code? 5 x 00000000 00000001 … void set(int *pa) // like a reference! { *pa = 5; } main() { int x = 1; set(&x); cout << x; } 00009240 00009241 00009242 00009243 00009244 00009245 00009246 00009247 00009248 00009249 00009250 5 CS31 - Spring13 - Section1J TA: Sepid Maz
arr r2p ptr 9242 References to Pointers short arr[3] = {2,-3, 1}; // global void dosth(short * & r2p) { r2p = &arr[1]; } main() { short *ptr = NULL; dosth(ptr); cout << *ptr; } 00000000 00000001 … 00009240 00009241 00009242 00009243 00009244 00009245 00009246 00009247 00009248 00009249 00009250 00009251 00009252 00009253 // ptr = &arr[1]; 2 -3 1 NULL r2p is a reference to a short pointer variable. So any time we refer tor2p, we’re really referring toptr! CS31 - Spring13 - Section1J TA: SepidMaz
arr r2p ptr NULL 9242 What If We Drop the Reference? short arr[3] = {2,-3, 1}; // global void dosth(short * & r2p) { r2p = &arr[1]; } main() { short *ptr = NULL; dosth(ptr); cout << *ptr; } 00000000 00000001 … 00009240 00009241 00009242 00009243 00009244 00009245 00009246 00009247 00009248 00009249 00009250 00009251 00009252 00009253 2 -3 1 NULL NULL r2p is a regular short pointer var. It gets a copy of ptr’s value. So when we refer tor2p, we’re referring to a copy ofptr!
Question:What does it print? 65 x pch pch2 main() { char ch = 'A'; char *pch,*pch2; pch = &ch; pch2 = pch; (*pch2)++; cout << ch; } 00000000 00000001 … 00002200 00002201 00002202 00002203 00002204 00002205 00002206 00002207 00002208 00002209 00002210 66 2200 2200 “Increment the value pointed to by pch2.” B CS31 - Spring13 - Section1J TA: Sepid Maz
Review A pointer is a memory address of a variable. We have already used pointer concepts through the use of • Call-by-reference • Passing an array identifiers through functions QUESTION: Using x as an integer and p as an int pointer, you should be able to know what's being accessed in each of these cases: x: &x: *p: p: &p: value of x address of x the value stored at the address that p refers to address that p refers to (value of p) address of p (p is a variable, and all variables have addresses. CS31 - Spring13 - Section1J TA: Sepid Maz
int *p1; int v1; v1 = -7; p1 = &v1; *p1 = 100; cout << v1 << endl; cout << *p1 << endl; Output? int *p1; *p1 = 100; cout << *p1 << endl; Output? CS31 - Spring13 - Section1J TA: Sepid Maz
Additional Materials • Check my webpage for additional materials. • Behnam CS31 - Spring13 - Section1J TA: Sepid Maz