diff --git a/pages/CSE332S/CSE332S_L4.md b/pages/CSE332S/CSE332S_L4.md index b90a43d..3c16f3d 100644 --- a/pages/CSE332S/CSE332S_L4.md +++ b/pages/CSE332S/CSE332S_L4.md @@ -1 +1,478 @@ -# Lecture 4 \ No newline at end of file +# Lecture 4 + +## Namespace details + +### Motivation + +Classes encapsulate behavior (methods) and state (member data) behind an interface. + +Structs are similar, but with state accessible. + +Classes and structs are used to specify self contained, cohesive abstractions. + +- Can say what class/struct does in one sentence. + +What if we want to describe more loosely related collections of state and behavior? + +Could use a class or struct + +- But that dilutes their design intent. + +### Namespace + +Cpp offers an appropriate scoping mechanism for **loosely related** aggregates: Namespaces. + +- Good for large function collections. + - E.g. a set of related algorithms and function objects +- Good for general purpose collections + - E.g. program utilities, performance statistics, etc. + +Declarative region + +- Where a variable/function can be used +- From where declared to end of declarative region + +### Namespace Properties + +Declared/(re)opend with `namespace` keyword. + +- `namespace name { ... }` +- `namespace name = namespace existing_name { ... };` + +Access members using scoping operator `::` + +- `std::cout << "Hello, World!" << std::endl;` + +Everything not declared in another namespace is in the global namespace. + +Can nest namespace declarations + +- `namespace outer { namespace inner { ... } }` + +### Using Namespaces + +The `using` keyword make elements visible. + +- Only apples to the current scope. + +Can add entire name space to the current scope + +- `using namespace std;` +- `cout << "Hello, World!" << endl;` + +Can also declare unnamed namespaces + +- Elements are visible after the declaration +- `namespace { int i = 42; }` will make `i` visible in the current file. + +## C-style vs. C++ strings + +### C++ string class + +```cpp +#include +#include + +using namespace std; + +int main (int argc, char *argv[]) { + string s = "Hello,"; + s += " World!"; + cout << s << endl; // prints "Hello, World!" + return 0; +} +``` + +- Using `` header +- Various constructions +- Assignment operator +- Overloaded operators +- Indexing operator, we can index cpp strings like arrays, `s[i]` +### C-style strings + +```cpp +#include +#include + +using namespace std; + +int main (int argc, char *argv[]) { + char *h = "Hello, "; + string sh = "Hello, "; + char *w = "World!"; + string sw = "World!"; + cout << (h < w) << endl; // this returns 0 because we are comparing pointers + cout << (sh < sw) << endl; // this returns 1 because we are comparing values of strings in alphabetical order + h += w; // this operation is illegal because we are trying to add a pointer to a pointer + sh += sw; // concatenates the strings + cout << h << endl; // this prints char repeatedly till the termination char + cout << sh << endl; // this prints the string + return 0; +} +``` + +- C-style strings continguous arrays of char + - Often accessed as `char *` by pointer. +- Cpp string class provides a rich set of operations. +- Cpp strings do "what you expected" as a programmer. +- C-style strings do "what you expected" as a machine designer. + +Use cpp strings for most string operations. + +## Cpp native array + +### Storing Other Data Types Besides `char` + +There are many options to store non-char data in an array. + +Native C-style arrays + +- Cannot add or remove positions +- Can index positions directly (constant time) +- Not necessary zero-terminated (no null terminator as ending) + +STL list container (bi-linked list) + +- Add/remove position on either end +- Cannot index positions directly + +STL vector container ("back stack") + +- Can add/remove position at the back +- Can index positions directly + +### Pointer and Arrays + +```cpp +#include + +using namespace std; + +int main (int argc, char *argv[]) { + int a[10]; + int *p = &a[0]; + int *q = a; + // p and q are pointing to the same location + ++q; // q is now pointing to the second element of the array +} +``` + +An array holds a contiguous sequence of memory locations + +- Can refer to locations using either array index or pointer location +- `int a[0]` vs `int *p` +- `a[i]` vs `*(a + i)` + +Array variable essentially behaves like a const pointer + +- Like `int * const arr;` +- Cannot change where it points +- Can change locations unless declared as const, eg `const int arr[10];` + +Can initalize other pointers to the start of the array + +- Using array name +- `int *p = a;` +- `int *p = &a[0];` + +Adding or subtracting int pointer n moves a pointer by n of the type it points to + +- `int *p = a;` +- `p += 1;` moves pointer by 1 `sizeof(int)` +- `p -= 1;` moves pointer by 1 `sizeof(int)` + +Remember that cpp only guarantees `sizeof(char)` is 1. + +### Array of (and Pointers to) Pointers + +```cpp +#include + +using namespace std; + +int main (int argc, char *argv[]) { + // could declare char ** argv + for (int i = 0; i < argc; i++) { + cout << argv[i] << endl; + } + return 0; +} +``` + +Can have array of pointers to pointers + +Can also have an array of pointers to arrays + +- `int (*a)[10];` +- `a[0]` is an array of 10 ints +- `a[0][0]` is the first int in the first array + +### Rules for pointer arithmetic + +```cpp +#include + +using namespace std; + +int main (int argc, char *argv[]) { + int a[10]; + int *p = &a[0]; + int *q = p + 1; + return 0; +} +``` + +You can subtract pointers to get the number of elements between them (no addition, multiplication, or division) + +- `int n = q - p;` +- `n` is the number of elements between `p` and `q` + +You can add/subtract an integer to a pointer to get a new pointer + +- `int *p2 = p + 1;` +- `p2` is a pointer to the second element of the array +- `p+(q-p)/2` is allowed but not `(p+q)/2` + +Array and pointer arithmetic: Given a pointer `p` and integer `n`, `p[n]` is equivalent to `*(p+n)`. + +Dereferencing a 0 pointer is undefined behavior. + +Accessing memory outside of an array may + +- Crash the program +- Let you read/write memory you shouldn't (hard to debug) + +Watch out for: + +- Uninitialized pointers +- Failing to check for null pointers +- Accessing memory outside of an array +- Error in loop initialization, termination, or increment + +### Dynamic Memory Allocation + +Aray can be allocated, and deallocated dynamically + +Arrays have particular syntax for dynamic allocation + +Don't leak, destroy safely. + +```cpp +Foo * baz (){ + // note the array form of new + int * const a = new int[3]; + a[0] = 1; a[1] = 2; a[2] = 3; + Foo *f = new Foo; + f->reset(a); + return f; +} + +void Foo::reset(int *a) { + // ctor must initialize to 0 + delete [] this->array_ptr; + this->array_ptr = a; +} + +void Foo::~Foo() { + // note the array form of delete + delete [] this->array_ptr; +} +``` + +## Vectors + +```cpp +#include +#include + +using namespace std; + +int main (int argc, char *argv[]) { + vector v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + // note that size_t is an unsigned type that is guaranteed to be large enough to hold the size of v.size(), determined by the compiler. + for (size_t i = 0; i < v.size(); i++) { + cout << v[i] << endl; + } + // this will print 1, 2, 3 + return 0; +} +``` + +### Motivation to use vectors + +Vector do a lot of (often tricky) dynamic memory management. + +- use new[] and delete[] internally +- resize, don't leak memory + +Easier to pass to functions + +- can tell you their size by `size()` +- Don't have to pass a separate size argument +- Don't need a pointer by reference in order to resize + +Still have to pay attention + +- `push_back` allocates more memory but `[]` does not +- vectors copy and take ownership of elements + +## IO classes + +```cpp +#include + +using namespace std; + +int main (int argc, char *argv[]) { + int i; + // cout == std::ostream + cout << "Enter an integer: "; + // cin == std::istream + cin >> i; + cout << "You entered: " << i << endl; + return 0; +} +``` + +`` provides classes for input and output. + +- Use `` for input +- Use `` for output + +Overloaded operators + +- `<<` for insertion +- `>>` for extraction (terminates on whitespace) + +Other methods + +- `ostream` + - `write` + - `put` +- `istream` + - `get` + - `eof` + - `good` + - `clear` + +Stream manipulators + +- `ostream`: `flush`, `endl`, `setwidth`, `setprecision`, `hex`, `boolalpha` (boolalpha is a manipulator that changes the way bools are printed from 0/1 to true/false). + +### File I/O + +```cpp +#include +#include + +using namespace std; + +int main (int argc, char *argv[]) { + ifstream ifs; + ifs.open("input.txt", ios::in); + ofstream ofs ("output.txt", ios::out); + if (!ifs.is_open() && ofs.is_open()) { + int i; + ifs >> i; + ofs << i; + } + ifs.close(); + ofs.close(); + return 0; +} +``` + +`` provides classes for file input and output. + +- Use `` for input +- Use `` for output + +Other methods + +- `open` +- `close` +- `is_open` +- `getline` parses a line from the file, defaults to whitespace +- `seekg` +- `seekp` + +File modes: + +- `in` let you read from the file +- `out` let you write to the file +- `ate` let you write to the end of the file +- `app` let you write to the end of the file +- `trunc` let you truncate the file +- `binary` let you read/write binary data + +### String Streams Classes + +```cpp +#include +#include +#include + +using namespace std; + +int main (int argc, char *argv[]) { + ifstream ifs("input.txt", ios::in); + if (!ifs.is_open()) { + string line_1, word_1; + getline(ifs, line_1); + istringstream iss(line_1); + iss >> word_1; + cout << word_1 << endl; + } + ifs.close(); + return 0; +} +``` + +`` provides classes for string streams. + +- Use `` for input +- Use `` for output + +Useful for scanning input + +- Get a line form file into a string +- Wrap a string into a stream +- Pull words off the stream + +```cpp +#include +#include + +using namespace std; + +int main (int argc, char *argv[]) { + if (argc < 3) return 1; + ostringstream argsout; + argsout << argv[1] << " " << argv[2] << endl; + istringstream argsin(argsout.str()); + float f,g; + argsin >> f; + argsin >> g; + cout << f << "/" << g << "is" << f/g << endl; + return 0; +} +``` + +Useful for formatting output + +- Using string as format buffer +- Wrapping a string into a stream +- Push formatted values into the stream +- Output the stream to file + +Program gets arguments as C-style strings + +Formatting is tedious and error prone in C-style strings (`sprintf`, etc.) + +`iostream` formatting is friendly. + + +