Skip to content

Commit

Permalink
Merge pull request #43 from philiplarsson/master
Browse files Browse the repository at this point in the history
Add lecture notes and 'good-to-know' to C++
  • Loading branch information
felixmulder committed Mar 30, 2016
2 parents e90fa6f + 4a88218 commit f306b76
Show file tree
Hide file tree
Showing 14 changed files with 2,469 additions and 0 deletions.
410 changes: 410 additions & 0 deletions EDA031-c++/good-to-know.md

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions EDA031-c++/lecture-notes/f1.md
@@ -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 (" ").








169 changes: 169 additions & 0 deletions EDA031-c++/lecture-notes/f10.md
@@ -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>


0 comments on commit f306b76

Please sign in to comment.