200 likes | 300 Views
CS 31 Discussion, Week 7. Faisal Alquaddoomi, faisal@cs.ucla.edu Office Hours: BH 2432, W 4:30-6:30pm, F 12:30-1:30pm. C-Strings Review. C-Strings are just char arrays, with some convenient functions for manipulating them End in a ‘ nul -terminator’ that signifies the end of the string
E N D
CS 31 Discussion, Week 7 Faisal Alquaddoomi, faisal@cs.ucla.edu Office Hours: BH 2432, W 4:30-6:30pm,F 12:30-1:30pm
C-Strings Review • C-Strings are just char arrays, with some convenient functions for manipulating them • End in a ‘nul-terminator’ that signifies the end of the string • C-Strings have special manipulation functions in the <cstring> library
2D Arrays Review • 2D arrays are like 1D arrays, except they have an extra dimension • by convention, the first dimension is the row, the second is the column • declare:intmyArray[5][10]; // 5 rows, 10 columns • access/change:myArray[2][3] = 888; // ^ item at row 2, col 3 is now 888 • 2D arrays can be statically allocated, but the second dimension (columns) must be specified • Similarly, when writing a function that takes a 2D array as a parameter, the second dimension must also be specified:void myFunc(char inArray[][5]) { /* body of function here… */ }
Notes on Project 5 • Just like any other type, you can have 2D arrays of C-strings, e.g.char doc[50][81]; // 50 lines, 80 chars + ‘\0’ each • Reading lines from istream is the same as from cin • Here’s a way to read 50 lines from an istream& (say, ‘mystream’):int lines = 0; while (lines < 50 && mystream.getline(doc[lines++],80)) continue;
Variables Revisited • Variables have a type, a name, and a value • Arrays are extensions of this idea • We can pass variables “by value” to functions, which causes their contents to be copied • We can also pass “by reference”, which changes the original variable when the reference changes • Arrays are always passed by reference…but why?
How Variables Are Stored int main() { int x; int y = 2; char c; double d; int q[5] = { 1, 2, 3 }; x = 3; c = ‘H’; d = 3.5; cout << “x: ” << x << endl; return 0; }
How Variables Are Stored int main() { int x; int y = 2; char c; double d; int q[5] = { 1, 2, 3 }; x = 3; c = ‘H’; d = 3.5; cout<< “x: ” << x << endl; return 0; } x y c d q[0] q[1] q[2] q[3] q[4] name: 3 2 ‘H’ 3.5 1 2 3 ? ? value:
Variable Storage, Scaled to Size x y c d name: 3 2 H 3.5 value: q[0] q[1] q[2] q[3] q[4] name: 1 2 3 ? ? value: 4 bytes
One More Attribute for Variables • In addition to a type, a name, and a value, variables also have an address • Just like the address of a house, it specifies where to find that variable in memory • Arrays are kind of like apartments, where each slot specifies a different place, all starting from the same address q @ 12 to 32 y @ 4 x @ 0 z @ 8 …
Variables with Addresses x y c d name: 3 2 H 3.5 value: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 q[0] q[1] q[2] q[3] q[4] name: 1 2 3 ? ? value: 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 .. 4 bytes
Operations on Addresses • From the previous example: • x has address 0, y has address 4, c has address 8, d is at 9 • q starts @17 and has slots @17, 21, 25, 29, and 33 • Retrieve the address of a variable/array using the ‘&’ operator, e.g.:cout<< (&x); // might print ‘0’ • Get the value at an address using the ‘*’ operator, e.g.:cout<< *(&x); // would print 3
Storing an Address, “Pointers” • Even though addresses are just numbers, they are very often stored in a special family of types • called the “pointer types”; an instance of this type is a “pointer” • For instance, the address of an int can be stored in a pointer type called int*, read as “pointer to int” • one pointer type per regular type, e.g. int has “int*”, char has “char*”, etc. • There’s a special pointer type called “void*”, but we’ll get to that later…
Creating and Assigning a Pointer • Assuming the previous code, this creates a pointer to ‘x’ and manipulates it a bit:// stores address of x in pxint* px = &x; // prints address of xcout << (int)(px) << endl; // changes x to 32 *(px) = 32; x y c d px name: 3 2 ‘H’ 3.5 0 … value:
Pointers to Arrays (and Pointer Arithmetic) • There is no difference between a pointer to a variable and a pointer to an array • …but this is where the type of the pointer starts to become useful • Set ‘pq’ to point to our ‘q’ array:int* pq = q; // q was already a pointer! // …q[0] is the value of the first element • Move ‘pq’ to the next element in ‘q’:pq = pq + 1; // moves pq 4b forward • ‘pq’ moves forward by 4 bytes because it’s a pointer to int, which is of size 4 • if it were a pointer to char, we’d move forward 1 byte and be in the middle of the first element rather than at the second element
Array Access Revisited • As established, ‘q’ is actually a pointer that points to the first element in its array • This is why we’ve had to pass the length of an array around all the time, because all ‘q’ knows is that it starts at some place and has a type • ‘q’s value tells it where to start, and its type tells it how to get to a particular element’s offset • (e.g. by multiplying size of type and desired element position, then adding it to the address of the first element, which is ‘q’) • The operator q[x] is actually *(q + size of type * index), e.g.: // let’s get the third element, slot 2cout << *(q + 4*2); // 4 == size of intin bytes // gets the value of the element // starting at q, then shifted over ‘x’ // units of the type’s size
Passing by Reference Revisited • The ‘reference’ that’s passed to a function is actually the address of the variable • C++ is doing you some confusing ‘favors’, like using ‘&’ on the argument and implicitly using ‘*’ every time the reference is mentioned • added to the language because passing pointers is so common
Passing by Reference, Part 2 • This code:void p(int& x) { x = 32; }int main() {int a; p(a);cout << a; /*etc*/ } • …is (almost) equivalent to this code:void p(int* x) { *x = 32; }intmain() {int a;p(&a);cout<< a;/*etc*/ }
Addresses and Pointers Review • All variables have an address in memory (as well as an amount of space they consume dictated by their type) • The address can be retrieved via the ‘&’ operator • The value at an address can be retrieved/changed using the ‘*’ operator on an address
Addresses and Pointers Review, Part 2 • A pointer is a special type used for holding addresses • Pointers can be manipulated using +, -, which moves them in ‘steps’ of their type’s size, e.g.:int* p; p = p + 3;// moves p (3*4) = 12 bytes forward in memory • Arrays are actually pointers to the first element • The subscript operator [] is implemented using pointer arithmetic; assuming q is an array of ints:q[x] == *(q+4*x)