diff --git a/lectures/classes/README.md b/lectures/classes/README.md index d5c7b10..feeb6ae 100644 --- a/lectures/classes/README.md +++ b/lectures/classes/README.md @@ -1,24 +1,8 @@ template: titleslide # Classes -## Rupert Nash, EPCC -## r.nash@epcc.ed.ac.uk +## Maurice Jamieson, EPCC +## m.jamieson@epcc.ed.ac.uk ---- -# Compiler explorer (Godbolt) - -A very useful tool is the Compiler Explorer - https://godbolt.org - -Type some code on the left and it will compiled with your choice of -very many compilers. - -Will show compiler errors/warnings/reports and can execute your -program. - -Can get shareable links to your code. - -??? - -The name comes from the creator, Matt Godbolt --- # User defined types @@ -54,7 +38,7 @@ Creating trivial types - give the class name then list the values to be assigned members, _in order_, inside braces: ```C++ -Complex mk_imaginary_unit() { +Complex mk_imaginary_unit(void) { return Complex{0, 1}; } ``` @@ -62,7 +46,7 @@ This is called aggregate initialisation. Alternatively: ```C++ -Complex mk_imaginary_unit() { +Complex mk_imaginary_unit(void) { Complex sqrt_m1; // Values are uninitialised sqrt_m1.re = 0; sqrt_m1.im = 1; @@ -76,10 +60,11 @@ Complex mk_imaginary_unit() { Using trivial types: ```C++ -void test() { +void test(void) { Complex z = mk_imaginary_unit(); assert(z.re == 0); assert(z.im == 1); + return 0; } ``` @@ -87,7 +72,8 @@ Any piece of code can access the member variables inside the object. ??? -This is probably something you're familiar with from other languages +This is probably something you're familiar with from other languages and the +same as C --- template: titleslide @@ -106,11 +92,11 @@ struct Complex { }; ``` -Now when you create an object it will be initialised to a know state +Now when you create an object it will be initialised to a known state for you: ```C++ -void test() { +void test(void) { Complex z; assert(z.re == 0); assert(z.im == 0); @@ -142,7 +128,7 @@ struct Complex { double im = 0.0; }; -Complex mk_imaginary_unit() { +Complex mk_imaginary_unit(void) { return Complex{0, 1}; } ``` @@ -246,11 +232,12 @@ other languages might call them methods For example: ```C++ -int main() { +int main(void) { std::string name; std::cin >> name; std::cout << "Hello, " << name << ". " << "Your name has " << name.size() << " characters." << std::endl; + return 0; } ``` ??? @@ -268,7 +255,7 @@ Typically these are declared in the class definition... // complex.hpp struct Complex { // Constructors as before - double magnitude() const; + double magnitude(void) const; double re = 0.0; double im = 0.0; @@ -286,7 +273,7 @@ If anyone asks, discussion of const is coming up! ```C++ // complex.cpp -double Complex::magnitude() const { +double Complex::magnitude(void) const { return std::sqrt(re*re + im*im); } ``` @@ -304,7 +291,8 @@ assert(z.magnitude() == 5.0); ??? The compiler inserts an implicit argument referring to the current -instance for us +instance for us, known as the 'this' pointer. See https://www.learncpp.com/cpp-tutorial/the-hidden-this-pointer/ +for more info --- # More on operator overloading @@ -328,6 +316,8 @@ Complex operator+(Complex const& a, Complex const& b) { } ``` +Here, `operator+=` is using the implicit `this` pointer + ??? Recall that these are just functions (with funny names) @@ -399,7 +389,7 @@ elsewhere in the class scope ```C++ class Greeter { std::string greetee; - void say_hello() const { + void say_hello(void) const { std::cout << "Hello, " << greetee << std::endl; } }; @@ -420,7 +410,7 @@ Compiler will say something like class Greeter { std::string greetee; public: - void say_hello() const { + void say_hello(void) const { std::cout << "Hello, " << greetee << std::endl; } }; @@ -438,7 +428,7 @@ Why is encapsulation worth bothering with? Enforces modularity and can without have to re-write the client code A class can declare another function (or class) its `friend` which -allows only that bit of code to touch its private members. +allows only that bit of code to access its private member variables. This is a controlled, partial relaxation of encapsulation that often makes the whole system more isolated. @@ -458,13 +448,14 @@ Variables can be qualified with the `const` keyword - compiler will give errors if you try ```C++ -int main() { +int main(void) { int const i = 42; std::cout << i << std::endl; // prints 42 i += 10; // error: cannot assign to variable 'i' with const-qualified type 'const int' + return 0; } ``` @@ -517,7 +508,7 @@ If they do not need to change an instance, then they should be marked ```C++ struct Complex { - double magnitude() const; + double magnitude(void) const; }; ``` @@ -606,7 +597,7 @@ void ScaleVector(double scale, std::vector& x) { // Multiply every element of x by scale } -void test() { +void test(void) { std::vector data = ReadLargeFile(); ScaleVector(-1.0, data); } @@ -659,12 +650,12 @@ class AtomList { std::vector velocity; std::vector charge; public: - std::vector const& GetCharge() const { + std::vector const& GetCharge(void) const { return charge; } }; -void analyse_md_data() { +void analyse_md_data(void) { AtomList const atoms = ReadFromFile(); std::vector const& charges = atoms.GetCharge(); std::cout << "Average charge = " @@ -699,7 +690,7 @@ reference and/or `const`: ??? -Note double ampersand in 2nd point - it's called a forwarding reference and we will +Note double ampersand in 2nd point - it's called a 'forwarding reference' and we will come back to it Refer back to the last slide codes and ask @@ -757,7 +748,8 @@ The exceptions being templates and `inline` functions if anyone asks Suffixes mostly meaningless to the compiler but don't surprise people! -Prefer earlier in the list +Prefer earlier in the list i.e. .hpp and .cpp to differentiate between C++ +and C code --- # Where to put these @@ -783,7 +775,7 @@ Complex operator+(Complex const& a, Complex const& b); ``` ??? -Draw attention to the include guard idiom +Draw attention to the include guard idiom - include the file only once --- # Exercise @@ -792,7 +784,7 @@ In your clone of this repository, find the `complex` exercise and list the files ``` -$ cd archer2-CPP-2021-07-20/exercises/complex +$ cd archer2-cpp/exercises/complex $ ls Makefile complex.cpp complex.hpp test.cpp ``` @@ -815,4 +807,4 @@ bugs! ??? -Ask who knows about make maybe? +Ask who knows about 'make' maybe? diff --git a/lectures/cpp-intro/README.md b/lectures/cpp-intro/README.md index bdd1593..a3b8c18 100644 --- a/lectures/cpp-intro/README.md +++ b/lectures/cpp-intro/README.md @@ -1,8 +1,8 @@ template: titleslide # A brief introduction to C++ -## Rupert Nash -## r.nash@epcc.ed.ac.uk +## Maurice Jamieson, EPCC +## m.jamieson@epcc.ed.ac.uk --- @@ -126,7 +126,7 @@ Every three years there is a new update to the International Standard Latest one, C++20, still not fully implemented by an compiler. Major new features are ranges, coroutines, concepts, and modules -Next one, in 2023, just beginning. Major features likely to include +C++23 is still in draft (N4944). Major features likely to include networking, string formatting, executors, and consolidation of new C++20 features @@ -141,6 +141,10 @@ C++20 features - Best online *reference* is (comes in other human languages too!) +- [cppreference.com](https://en.cppreference.com/w/cpp/compiler_support#cpp20) + also lists the level of C++ standards support (including C++20) for a number of compilers + (e.g. GCC, Clang, MSVC, Intel C++) + - Scott Meyers, "Effective Modern C++", 2014. This is *the* book to get once you know your way around C++, but you want to improve. Teaches lots of techniques and rules of thumb for writing correct, @@ -160,8 +164,9 @@ name: hello ```C++ #include -int main() { +int main(void) { std::cout << "Hello, world!" << std::endl; + return 0; } ``` @@ -194,8 +199,17 @@ template: hello - The compiler and OS arrange for this to be called when you run it. -- (Not shown, but you can also get the command line arguments) +- The `return 0` statement indicates to the OS that no error occured. + +- (You can also get the command line arguments but `void` here means we + aren't using them). + +??? + +The 'main' function is the 'entry point' of the program and its integer return value +allows a program or error status to be returned to the operating system. +There are 'main' function exit (return) values defined in --- template: hello @@ -213,9 +227,9 @@ template: hello template: hello - The standard library uses the bitwise left shift operator (`<<`) to - mean stream insertion + mean stream insertion: -- I.e. output the right hand side to the left. + - i.e. output the right hand side to the left. - Every statement in C++ must be terminated with a semicolon (`;`) @@ -235,30 +249,34 @@ __Your machine__ : you need a C++ compiler that supports at least C++11. If you use Windows and MSVC we may not be able to help much... Sorry! -__Cirrus__: You have log in details. +__ARCHER2__: You have log in details. Once connected you need to load the up-to-date compilers: ``` -module load gcc/8.2.0 +module load gcc/10.2.0 ``` +??? + +There are later versions of GCC on ARCHER2 but 10.2.0 is the default version + --- # Getting the source code All these slides and the exerices are available on GitHub: -https://github.com/EPCCed/archer2-CPP-2021-07-20 +https://github.com/EPCCed/archer2-cpp You also can view the slides and other materials in a browser by going -to https://EPCCed.github.io/archer2-CPP-2021-07-20/ +to https://EPCCed.github.io/archer2-cpp In the terminal, you need to use git get a copy of the exercises: ``` -git clone https://github.com/EPCCed/archer2-CPP-2021-07-20 +git clone https://github.com/EPCCed/archer2-cpp ``` Then you can change to the directory with this simple program ``` -cd archer2-CPP-2021-07-20/lectures/cpp-intro/hello +cd archer2-cpp/lectures/cpp-intro/hello ``` --- @@ -284,6 +302,23 @@ Run it: ./hello ``` +--- +# Compiler explorer (Godbolt) + +A very useful tool is the Compiler Explorer - https://godbolt.org + +Type some code on the left and it will compiled with your choice of +very many compilers. + +Will show compiler errors/warnings/reports and can execute your +program. + +Can get shareable links to your code. + +??? + +The name comes from the creator, Matt Godbolt + --- template: titleslide # A few things @@ -350,7 +385,7 @@ template: titleslide | Type | Description | |-------------|-------------| -| `void` | Nothing - used to indicate a function returns no value.| +| `void` | Nothing - used to indicate a function takes and/or returns no value.| | `bool` | `true` or `false` | | `int` | Standard *signed* integer for your machine. *At least* 16bits. *Usually* 32 bits.| | `double` | Double-precision floating point. *Usually* an IEEE 754 64 bit number.| @@ -384,9 +419,10 @@ use it. #include #include -int main() { +int main(void) { std::string message = "Hello, world"; std::cout << message << std::endl; + return 0; } ``` @@ -395,7 +431,7 @@ Character encoding in the standard library is a bit of a mess. Partially fixed in C++20 -Find a library if you need to do serious text handling because Unicode +Find a library e.g. Boost, if you need to do serious text handling because Unicode is super complicated --- @@ -409,12 +445,13 @@ A function encapsulates a piece of code between braces (curly brackets, `{}`) and gives it a name so you can use it later. ```C++ -void say_hello() { +void say_hello(void) { std::cout << "Hello, world!" << std::endl; } int main(int argc, char* argv[]) { say_hello(); + return 0; } ``` ??? @@ -423,7 +460,10 @@ You declare function by first giving the return type (`void`) Then the name (`say_hello`) -Then the list of zero or more parameters +Then the list of zero or more parameters. If the parameter list is zero, +then you can use empty brackets but just as we would use 'void' to mark that +a function doesn't return a value, we can use 'void' within the brackets to +indicate that the function doesn't take parameters. --- # Functions @@ -441,7 +481,7 @@ int sum(int a, int b) { } ``` -Can alse use trailing return type (aka "east end functions"): +Since C++11, we can alse use a _trailing return type_ (aka "east end functions"): ```C++ auto sum(int a, int b) -> int { return a + b; @@ -458,17 +498,22 @@ In this case, by us telling it later --- # Functions -To use a function - to "call" it - you give its name and then provide +To use a function, or "call" it, you give its name and then provide the arguments in parentheses ``` -int main () { +int main (void) { int x = 42; std::cout << "Total = " << sum(x, 100) << std::endl; + return 0; } ``` -The parameters to the function must match the (a) declaration. +The parameters to the function must match the declaration. + +The `return 0` statement in the `main(void)` function is optional but you +have to have a `return` statement in all other functions that return a +value. --- # Function overloading @@ -532,12 +577,16 @@ We'll come back to this! ??? +Here, 'data_file' is given the type 'std::string' by the compiler using +"type inference" + In general we'd recommend using auto quite a lot "Almost always auto" Why? Can't have an uninitialized variable + Add types - on RHS as constructors - when you need to ensure the type of something (is known to the reader). @@ -549,7 +598,7 @@ of something (is known to the reader). #include #include -void say_hello() { +void say_hello(void) { std::cout << "Hello, world!" << std::endl; } @@ -561,6 +610,8 @@ int main(int argc, char* argv[]) { // Have the program greet the user by name say_hello(name); + + return 0; } ``` diff --git a/lectures/cpp-intro/auto/auto.cpp b/lectures/cpp-intro/auto/auto.cpp new file mode 100644 index 0000000..b303f8c --- /dev/null +++ b/lectures/cpp-intro/auto/auto.cpp @@ -0,0 +1,16 @@ +#include + +// Needs C++20 +auto add(auto x, auto y) { + return x+y; +} + +int main(void) { + auto num = 42; + auto real = 42.0; + + std::cout << add(num,10) << std::endl; + std::cout << std::fixed << add(real,10.0) << std::endl; + + return 0; +} \ No newline at end of file diff --git a/lectures/cpp-intro/hello/hello.cpp b/lectures/cpp-intro/hello/hello.cpp index 6c3459b..46c8be6 100644 --- a/lectures/cpp-intro/hello/hello.cpp +++ b/lectures/cpp-intro/hello/hello.cpp @@ -2,4 +2,5 @@ int main(int argc, char* argv[]) { std::cout << "Hello, world" << std::endl; + return 0; } diff --git a/lectures/cpp-intro/sum/sum.cpp b/lectures/cpp-intro/sum/sum.cpp new file mode 100644 index 0000000..26bc978 --- /dev/null +++ b/lectures/cpp-intro/sum/sum.cpp @@ -0,0 +1,30 @@ +#include + +int sum(int a, int b) { + return a + b; +} + +double sum(double a, double b) { + return a + b; +} + +int i1 = 1; +int i2 = 2; +double d1 = 1.0; +double d2 = 2.0; +unsigned u42 = 42; +std::string name = "Alice"; +std::string file = "data.csv"; + + +int main(void) { + std::cout << sum(i1, i2) << std::endl; + std::cout << sum(3, 72) << std::endl; + std::cout << sum(i1, u42) << std::endl; + std::cout << sum(d2, d1) << std::endl; + std::cout << sum(d2, 1e6) << std::endl; + std::cout << sum(d2, i1) << std::endl; + std::cout << sum(name, file) << std::endl; + + return 0; +} \ No newline at end of file