Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from philiplarsson/master
Add lecture notes and 'good-to-know' to C++
- Loading branch information
Showing
14 changed files
with
2,469 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Föreläsning 1 | ||
|
||
## Compiling | ||
To compile, and run use: | ||
|
||
g++ -c hello.cc | ||
g++ -o hello hello.c | ||
./hello | ||
|
||
- g++ is the GNU C++ compiler | ||
|
||
- clang++ is another compiler | ||
|
||
- if **-o** is omitted, the compiler generates an executable named *a.out* | ||
|
||
- to generate warnings about problematic constructs, one can use `g++ -Wall` (<https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html>). `Wextra` is anothe one that might be useful. | ||
|
||
## Parameters on the command line | ||
|
||
int main(int argc, char* argv[]) { ... } | ||
|
||
- **argc** is the number of parametrs, including the program name. **argv** is an array of C-style strings that contains the parametrs. | ||
|
||
## Reading and writing | ||
- **cin** and **cout** are input and output streams (stdin and stdout) | ||
|
||
- **>>** is the input operator, reads whitespace-separeted tokens. Returns *false* on end-of-file. | ||
|
||
- **<<** is the output operator. | ||
|
||
## Class Definiton | ||
class Point { | ||
public: | ||
Point(double ix, double iy); // constructor, same name as class | ||
double getX() const; // const - does not modify the state of the object | ||
double getY() const; | ||
void move(double dx, double dy); // does modify, not const | ||
private: | ||
double x; // attributes | ||
double y; | ||
}; // note semicolon | ||
|
||
- methods are called member functions in C++, attribuets are called member variables | ||
|
||
- member functions are only declared here. The definitions are in a separate file | ||
|
||
- *public* and *private* "sections". Arbitrary order, *private* is default. | ||
|
||
- one can use *struct* instead of *class*. The difference is that *public* is default instead of *private*. | ||
|
||
### Definition of member functions | ||
The functions body is in a seperate file. Can be in the same file, but should mostly be used if the functions are used often and short. | ||
|
||
Point::Point(double ix, double iy) { | ||
x = ix; // this is ok but there are better ways to | ||
y = iy; // initialize member variables, see next slide | ||
} | ||
double Point::getX() const { | ||
return x; | ||
} | ||
double Point::getY() const { | ||
return y; | ||
} | ||
void Point::move(double dx, double dy) { | ||
x += dx; | ||
y += dy; } | ||
|
||
## Allocation of Objects | ||
In C++ objects can be allocated in several different ways. | ||
|
||
- stack allocated (automatic) - local variables, accessed by name | ||
|
||
- `Point p1(1, 2);` | ||
|
||
- heap allocated - like in Java, accessed though pointer | ||
|
||
- `Point* p = new Point(1, 2);` | ||
`double xLoc = p->getX();` | ||
`...` | ||
`delete p;` | ||
|
||
- **Point \*p** means that p is a pointer. **p->** is used to access members in the object. The lifetime of a heap-allocated object is between **new** and **delete**. If you forget to delete an object, the result is a *memory leak*. | ||
|
||
|
||
# Notes from book | ||
Chapter 1 | ||
|
||
## File suffix | ||
Different compilers uses different suffix conventions. The most common are: | ||
|
||
- .cc | ||
|
||
- .cxx | ||
|
||
- .cpp | ||
|
||
- .cp | ||
|
||
- .C | ||
|
||
## Input output | ||
To use output and input we need to tell the compiler that we want to use the `iostream` library. This is done with: `#include <iostream>` | ||
Typically we put all `#include` at the beginning of the source file. | ||
|
||
- **cin** (see-in) handles input, referred to as the standard input | ||
|
||
- **cout** (see-out) handles output, referred to as standard output | ||
|
||
- **cerr** (see-err) handles warning and error messages, referred as the standard error | ||
|
||
- **clog** (see-log) handels general information about the execution of the program | ||
|
||
Example: | ||
```c++ | ||
std::cout << "Enter two numbers: " << std::endl; | ||
int v1 = 0, v2 = 0; | ||
std::cin >> v1 >> v2; | ||
``` | ||
The example above uses **std::cout** and **std::endl** to indicate that the names cout and endl are defined inside the **namespace** named std. | ||
Namespaces allow us to avoid inadvertent collisions between the names we define and uses of those same names inside a library. All the names defined by the standard library are in the **std** namespace. | ||
|
||
One drawback of this is that when we want to use something from the standard library, we must explicitly say that we want to use it from the **std** namespace. Writing `std::cout` uses the scope operator (**::**) to say that we want to use the name *cout* that is defined in the namespace **std**. | ||
|
||
## Comments | ||
Comments can be single line and paired. A single line is started with double dash `//` and ends with a newline. | ||
A paired comment uses two delimiters `/*` and `*/`. Example: | ||
|
||
```c++ | ||
// this is a single line comment | ||
/* | ||
this comment can span | ||
multiple lines | ||
*/ | ||
``` | ||
|
||
## Classes | ||
We use headers to access classes defined for our own application. Header files usually have a suffix of **.h** but some programmers use .H, .hpp, or .hxx. | ||
The standard library headers typicaly have no suffix at all. Compilers usually don't care about the form of header file names, but IDEs sometimes do. Moreower headers from the standard library are enclosed in angle brackets (< >). Those that are not part of the library (such as our own header files) are enclosed in double quotes (" "). | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
--- | ||
title: Föreläsning 10 | ||
date: 17-03-2016 | ||
subtitle: 'Lecturer: Roger' | ||
--- | ||
|
||
# Föreläsning 10 | ||
|
||
## Algorithms and Functions | ||
Functions and function objects are used to parametize and algorithm with an "operation". The library function `for_each` traverses a range and performs an operation on all elements. | ||
|
||
### for each with regular functions | ||
`for_each` can be used with regular functions: | ||
|
||
``` | ||
void clear(int& value) { value = 0; } | ||
void print(int value) { cout << value << " "; } | ||
int main() { | ||
vector<int> v = {10, 20, 30, 40, 50}; | ||
for_each(v.begin(), v.end(), print); | ||
cout << endl;; | ||
for_each(v.begin(), v.end(), clear); | ||
for_each(v.begin(), v.end(), print); | ||
cout << endl; | ||
} | ||
``` | ||
|
||
### Function Examples - Finding | ||
The library algorithm `find_if` returns an iterator to the first element for which the function pred returns true. | ||
|
||
In C++, we can write a lambda function at the place of the call (`pred` above). | ||
|
||
``` | ||
bool exists_smaller(const vector<int>& v, int value) { | ||
return find_if(v.begin(), v.end(), | ||
[value](int x) {return x < value; }) != v.end(); | ||
} | ||
``` | ||
|
||
- `[value]` access the variable `value` in the current scope. Variables can also be captured by reference: `[&value]`. | ||
|
||
- `(int x)` normal parameter list | ||
|
||
- `) {` the return type is deduced from the return statemetn. Can be specified as `-> bool`. | ||
|
||
- `{ ... }` is the function body | ||
|
||
#### Lambda | ||
When you define a lambda, the compiler writes a function class and creates a function object: | ||
|
||
``` | ||
auto less = [value](int x) -> bool { return x < value; } | ||
``` | ||
|
||
### Function Examples - Sort | ||
The algorithm `sort(beg, end)` sorts an iterator range in ascending order (values are compared with <). A function defining the sort order can be supplied as a third argument. To sort in descending order (comparing values with `>`): | ||
|
||
``` | ||
vector<string> v; | ||
... | ||
sort(v.begin(), v.end(), | ||
[](const string &a, const string &b) { return a > b; } ); | ||
``` | ||
Simple function objects like `greater`, `less`, `equal_to` are available in the library. They can be used like this: | ||
|
||
``` | ||
sort(v.begin(), v.end(), greater<string>() ); | ||
``` | ||
|
||
## Algorithms | ||
There are about 100 algorithms in the header `<algorithm>`. They can be classified as follows: | ||
|
||
- **Nonmodifying**: look at the input but don't change the values or the roder between elements (`find`, `find_if`, `count`, ...) | ||
|
||
- **Modifying**: change values, or create copies of elements with changed values (`for_each`, `copy`, `fill`, ...). | ||
|
||
- **Removing**: remove elements (`remove`, `unique`, ...) | ||
|
||
- **Mutating**: change the order between elements but not their values (`reverse`, `random_shuffle`, ...) | ||
|
||
- **Sorting**: a special kind of mutating algorithms (`sort`, ...) | ||
|
||
- **Sorted Range**: require that the input is sorted (`binary_search`, ...) | ||
|
||
- **Numeric**: for numeric processing (`accumulate`, `inner_product`, ...) | ||
|
||
### Algorithm Notes | ||
- The input to an algorithm is one or more iterator ranges `[beg, end]`. If the algorithms writes elements, the start of the output range is given as an iterator. | ||
|
||
- Return values are often iterators | ||
|
||
- Some containers have specialized algorithms that are more efficient than the library algorithms, for instance `map::find` for finding a value in a map (binary search tree). | ||
|
||
### Finding Algorithms Examples | ||
Find algorithms returns the `end` iterator if the value isn't found. | ||
|
||
Some examples: | ||
|
||
``` | ||
vector<string> v = ...; | ||
cout << "There are " << count(v.begin(), v.end(), "hello") << " hello's in v" << endl; | ||
vector<string> v2 = {"hello", "hej", "davs"}; | ||
auto it = find_first_of(v.begin(), v.end(), v2.begin(), v2.end()); | ||
``` | ||
|
||
### Modifying Algorithms Examples | ||
The following examples use strings - strings have iterators that can be used with the library algorithms. | ||
|
||
```cpp | ||
string s = "This is a sencence"; | ||
|
||
// convert to lowercase | ||
transform(s.begin(), s.end(), s.begin(), ::tolower); | ||
|
||
// print all non blanks | ||
copy_if(s.begin(), s.end(), ostream_iterator<char>(cout), | ||
[](char c) { return c != ' '; } ); | ||
|
||
// fill s with blanks | ||
fill(s.begin(), s.end(), ' '); | ||
``` | ||
### Removing Algorithms | ||
The most important fact about the removing algorithms is that they don't actually remove elements from a container (since the algrithms have iterators as input they don't know which container to remove from, or how). Instead they reorder the elements based on a criterion. | ||
``` | ||
vector<int> v = {1, 3, 2, 6, 3, 3, 4}; | ||
auto it = remove(v.begin(), v.end(), 3); | ||
// v contains {1, 2, 6, 4, ...}, it points after the 4 | ||
// vector::erase really removes elements: | ||
v.erase(it, v.end()); | ||
v = {1, 3, 3, 5, 7, 7, 7, 8, 9, 9}; | ||
v.erase(unique(v.begin(), v.end()), v.end()); | ||
``` | ||
### Mutating and Sorting Algorithms | ||
```cpp | ||
vector<int> v = {1, 4, 44, 3, 15, 6, 5, 7, 7, 4, 22, 1}; | ||
// reorder so odd numbers precede even numbers | ||
partition(v.begin(), v.end(), [](int x) { return x % 2 != 0; } ); | ||
// shuffle the elements (requires random access iterators) | ||
random_shuffle(v.begin(), v.end()); | ||
// sort until the first 5 elements are correct | ||
partial_sort(v.begin(), v.begin() + 5, v.end()); | ||
``` | ||
|
||
### Algorithm Summary | ||
- Every C++ programmer should be familiar with the algorithms. | ||
|
||
- The algorithms are easy to use, well tested and efficient. | ||
|
||
- We have only shown a few of the algorithms. Look in a book or at the web: | ||
- <http://en.cppreference.com/w/cpp/algorithm> | ||
- <http://www.cplusplus.com/reference/algorithm> | ||
|
||
|
Oops, something went wrong.