You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: part_one/01_running.md
+11-11Lines changed: 11 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
-
# Compiling & Running
1
+
# Compiling & Running C++ Code
2
2
```{index} compiling
3
3
```
4
4
5
-
Whereas Python is mostly fairly simple to get working with straight away, especially in interactive mode, C & C++ have a few extra hurdles before you can get the computer to run your code. Your program must be compiled (and sometimes linked to other external standard or third party libraries) to produce a separate executable file, before that file can be run to solve your problem. In this section we present a number of ways of approaching this, listed in order of ease of use.
5
+
Whereas Python is mostly fairly simple to get working with straight away, especially when working in interactive mode in a terminal interpretter session or a Jupyter notebook, C & C++ have a few extra hurdles before you can get the computer to run your code. Your program must be compiled (and sometimes linked to other external standard or third party libraries) to produce a separate executable file containing native machine instructions for your system, before that file can be run to finaly solve your problem. In this section we present a number of ways of approaching this, listed in order of ease of use.
6
6
7
7
## Web based solutions
8
8
```{index} compiling:web-based
@@ -21,13 +21,13 @@ On each of these platforms you can cut & paste code from the examples in this pr
21
21
```{index} compiling: via docker
22
22
```
23
23
24
-
A more local option is to take advantage of the combined power of Docker and Visual studio code to provide files which you can often compile with one click.
24
+
A more local option is to take advantage of the combined power of Docker and Visual Studio Code to provide files which again you can often compile with one click.
25
25
26
26

27
27
28
28
To begin, fork the accompanying [examples repository](https://github.com/ese-msc/c-examples) and download it, then with Docker desktop running, open your local repository in VS code. You will be presented with a query banner "Folder contains a Dev Container configuration file. Reopen folder to develop in a container (learn more).". Select "Reopen in Container". This will restart the VS Code editor window, while connecting to a Docker container build from the repository [C examples Dockerfile](https://ese-msc/c-examples/.devcontainer/Dockerfile). This container has `git` and `Python` installed, together a working linux C++ compiler (the GNU compiler) and some useful VS Code extensions installed.
29
29
30
-
For simple non-interactive C++ files, you can now build & run them with the Run Code button (ctrl+alt+N). For interactive files, you will need to run the program yourself using (for a file `hello.cpp` in the current directory) a command like:
30
+
For simple, non-interactive C++ programmes contained in a single file, you can now build & run them with the Run Code button (ctrl+alt+N). For interactive files, you will need to run the program yourself using (for a file `hello.cpp` in the current directory) a command like:
31
31
32
32
```
33
33
g++ -o hello hello.cpp
@@ -62,29 +62,29 @@ Most Mac users on the course will already have Homebrew installed, but for those
62
62
brew install gcc
63
63
```
64
64
65
-
will install a recent version of `gcc` (version 13 as of early December 2023) as well as placing it in your standard path. Once installed, (and having openned a new terminal) you can confirm that things work by running the following command in a terminal
65
+
will install a recent version of `gcc` (version 14 as of early December 2024) as well as placing it in your standard path. Once installed, (and having openned a new terminal) you can confirm that things work by running the following command in a terminal
66
66
67
67
```
68
-
gcc-13 --version
68
+
gcc-14 --version
69
69
```
70
70
71
71
You should see a response something like
72
72
73
73
```
74
-
gcc-13 (Homebrew GCC 13.2.0) 13.2.0
75
-
Copyright (C) 2023 Free Software Foundation, Inc.
74
+
gcc-14 (Homebrew GCC 14.2.0) 13.4.0
75
+
Copyright (C) 2024 Free Software Foundation, Inc.
76
76
This is free software; see the source for copying conditions. There is NO
77
77
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
78
78
```
79
79
80
80
To compile a C++ file called `hello.cpp` into an exectuable called `hello`, then run it, use a command like
81
81
82
82
```
83
-
g++-13 -o hello hello.cpp
83
+
g++-14 -o hello hello.cpp
84
84
./hello
85
85
```
86
86
87
-
Here `g++-13` is the name of your new GNU C++ compiler (version number 13), the `-o` option specifies the name of the output file (the default is `a.out`) and we must list the `.cpp` source file to compile into it. The second line then runs our new executable file which we have just compiled.
87
+
Here `g++-14` is the name of your new GNU C++ compiler (specifically, version number 14), the `-o` option specifies the name of the output file (the default is `a.out`) and we must list the `.cpp` source file to compile into it. The second line then runs our new executable file which we have just compiled.
88
88
89
89
Remember, we only need to compile once, and then we can run the executable as many times as we like. If we make any changes to the source code, we must recompile before we can run the new version and see the results.
Copy file name to clipboardExpand all lines: part_one/02_hello_world.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,4 @@
1
-
# Hello World!
1
+
# A "Hello World!" Program in C++
2
2
3
3
## Introduction
4
4
@@ -40,7 +40,7 @@ Finally, in C/C++ we **must** use the double quotes `"` to indicate a string (th
40
40
41
41
## Hello World in C++
42
42
43
-
A C++ based hello world function might look something like the following:
43
+
A canonical C++ based hello world function might look something like the following:
44
44
45
45
_hello.cpp_:
46
46
```c++
@@ -52,14 +52,14 @@ _hello.cpp_:
52
52
}
53
53
```
54
54
55
-
You'll see that in this case, the code looks very similar to the C example. In fact, most C code is valid C++ code (possibly with a few small changes). The only thing that looks different is that rather than using a function like `printf` we are using the special `<<` operator (i.e. a token which works a bit like `+` or `-`) to send our message to `std::cout`, an "output stream" which in this case represents printing to the screen.
55
+
You'll see that in this case, the code looks very similar to the C example. In fact, most C code is valid C++ code (possibly with a few small changes). The only major thing that looks different is that rather than using a function like `printf` we are using the special `<<` operator (i.e. a token which works a bit like `+` or `-`) to stream our message to `std::cout`, an "output stream" which in this case represents printing to the screen. We could have used `"\n"` again to end the line, but in C++ we can also use `std::endl` to do the same thing, as well as flushing the output buffer (which can be useful in some cases).
56
56
57
57
## Some key differences from Python
58
58
59
-
1. Whitespace doesn't matter (although it still makes things easier to read when code is nicely formatted).
60
-
2. Individual statements *must* end with a `;`.
61
-
3.The code starts running at the top of the `main` function. There can only be one `main` in a given programme.
62
-
4. Functions (and variables) have a fixed data type associated with them.
59
+
1. Whitespace in your doesn't matter (although it still makes things easier to read when code is nicely formatted). Instead `{}` are used to define blocks of code.
60
+
2. Individual statements *must* end with a `;`. It's easy to forget this at first, but the compiler will remind you (often in a way that's hard to understand until you are used to it).
61
+
3.Rather than starting at the top of the file, the code starts running at the top of the `main` function. There can only be one `main` function in a given programme.
62
+
4. Functions (and variables) _must_have a fixed data type associated with them the first time they are declared.
63
63
64
64
65
65
## Exercise: Run the Hello World programs
@@ -70,7 +70,7 @@ Run the three different programs in Python, C and C++. You already know how to r
70
70
71
71
Once you can run the programs, try using the variable based version to try changing the message:
72
72
- What happens if you leave out the `\n` instruction in the C example?
73
-
- Can you add a second line of text, first in the same variable, then in a second one?
73
+
- Can you add a second line of text, fist in the same call to `printf`/`std::cout`, then by adding a second one?
Copy file name to clipboardExpand all lines: part_one/03_simple_math.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -135,7 +135,7 @@ Note that unlike in Python, plotting in C++ is hard work, so we're just printing
135
135
136
136
## Quadrature
137
137
138
-
Now we'll implement two quadrature methods, the midpoint and the trapezium rules. We'll start with the Python code (see the Computational Mathematics course for the annotated versions):
138
+
Now we'll implement two quadrature methods, the midpoint and the trapezium rules. We'll start with the Python code again (see the Computational Mathematics course notes for the annotated versions):
doublemidpoint_rule(double a, double b, double (*func)(double), int number_intervals=10) {
180
180
double interval_size = (b - a)/number_intervals;
@@ -214,9 +214,9 @@ int main(void) {
214
214
}
215
215
```
216
216
217
-
Note that we've had to include the `cmath` header to get access to the `sin` function. We've also had to declare the function `f` as taking a double and returning a double, and then pass it as an argument to the quadrature functions. This is because C++ doesn't have a built-in `sin` function, but instead has a `sin` function for each of the floating point types (e.g. `float`, `double`, `long double`), and the compiler needs to know which one we want to use.
217
+
Note that we've had to include the `cmath` header to get access to the `sin` function. We've also had to declare the function `f` as taking a double as input and returning a double, and then pass it in as an argument to the quadrature functions. This is because C++ doesn't have a single unique built-in `sin` function, but instead has a `sin` function for each of the floating point types (e.g. `float`, `double`, `long double`) in its `cmath` library, and the compiler needs to know which one we want to use.
218
218
219
-
The declaration and use of function pointers in the C++ versions of the `midpoint_rule` and `trapezium_rule` is more complicated than the Python version, but it's not too bad once you get used to it. We'll talk more about this in a later section.
219
+
The declaration and use of function pointers in the C++ versions of the `midpoint_rule` and `trapezium_rule` is more complicated than the Python version, but it's not too impossible to remember once you get used to it. We'll talk more about this in a later section.
Copy file name to clipboardExpand all lines: part_one/04_input-output.md
+9-8Lines changed: 9 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,10 @@
1
-
# Programs with input
1
+
# C++ Programs accepting inputs
2
2
3
3
Since C++ programmes are compiled, we don't have the same flexibility to change the behaviour of the program at runtime as we do with Python. However, we can still take input data from the user in a number of ways.
4
4
5
5
## Taking input from the keyboard
6
6
7
-
The counterpart to `std::cout` is `std::cin`. It's usage is similar but "in the other direction". For example:
7
+
The counterpart to `std::cout` is `std::cin`, just as the counterpart to `print()` in Python is `input()`. The usage of `std::cin`is similar to `std::cout`but "in the other direction", using the `>>` operator. For example, the following C++ program asks for the user's name and then greets them:
8
8
9
9
```c++
10
10
#include<iostream>
@@ -28,7 +28,7 @@ To run this using Docker plus VS code, you will need to run the compile command
28
28
```
29
29
```
30
30
31
-
The `>>` operator will automatically convert the input into an appropriate form for the datatype (as long as it's one of the defaults). In the example above, this is just to a string, but we can also convert to integers or floating point numbers. Let's have an example, for example a program to calculate the mean of a sequence of floating point numbers.
31
+
The `>>` operator will automatically convert the input into an appropriate form for the datatype (as long as it's one of the standard C++ types like `int`, `float`, `double` etc. ). In the example above, this is just to a string, but we can also convert to integers or floating point numbers. Let's have an example, for example a program to calculate the mean of a sequence of floating point numbers.
32
32
33
33
```c++
34
34
#include<iostream>
@@ -92,15 +92,15 @@ int main()
92
92
{
93
93
FILE *fptr;
94
94
95
-
fptr = fopen("example.txt","w"); // A lot like the Python open function
95
+
fptr = fopen("example.txt","w"); // A lot like the Python open function
96
96
97
97
if(fptr == NULL) // We have to do our own error checks
98
98
{
99
-
printf("Error!");
99
+
printf("File read error!");
100
100
exit(1);
101
101
}
102
102
103
-
fprintf(fptr,"%d", 1000); // Write a number
103
+
fprintf(fptr,"%d", 1000); // Write a number
104
104
fclose(fptr);
105
105
106
106
return 0;
@@ -110,22 +110,23 @@ int main()
110
110
to read a file we'd use
111
111
```c
112
112
int num;
113
-
fptr = fopen("example.txt","r");
113
+
fptr = fopen("example.txt","r");
114
114
fscanf(fptr,"%d", &num);
115
115
```
116
116
instead. We'll explain the use of `*` and `&` in the code above in Part III.
117
117
118
118
For C++ we can treat files like we do the screen by treating them as _streams_ and reading or writing with the `<<` and `>>` operators. So to write ouput
119
119
120
120
```c++
121
+
#include <iostream>
121
122
#include <fstream>
122
123
123
124
int main () {
124
125
125
126
std::fstream fs;
126
127
fs.open ("example.txt", std::fstream::out);
127
128
128
-
fs << 1000; // write 1000 to example.txt
129
+
fs << 1000 << std::endl; // write 1000 to example.txt
Copy file name to clipboardExpand all lines: part_three/01_pointers.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ b = a
13
13
b[0] =1
14
14
print(a)
15
15
```
16
-
Running the above code in the Python interpretter gives the output `[1]`. This is because the names `a` and `b` have both been bound to the same list object, and updating the list via one name updates it via the other. C and C++ allow similar behaviour usuing a concept called "pointer"s.
16
+
Running the above code in the Python interpretter gives the output `[1]`. This is because the names `a` and `b` have both been bound to the same list object, and updating the list via one name updates it via the other. C and C++ allow similar behaviour using a concept called "pointers".
17
17
18
18
A C style pointer holds a location (usually called an address) in your computer's memory, along with an attached data type. This address can be looked up ("dereferenced") to get hold of the underlying value to:
Copy file name to clipboardExpand all lines: part_two/01_datatypes.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,6 +80,8 @@ int main() {
80
80
since it is permissible (though definitely not advisable) to declare variables anew in a new block.
81
81
82
82
## Type conversion
83
+
```{index} type conversion
84
+
```
83
85
84
86
C-like languages have a number of inbuilt rules which they use to convert values from one type to another. Typically they are converted into whatever type has the larger range, and the expression is then evaluated in that type. This means that code such as
Copy file name to clipboardExpand all lines: part_two/02_operators.md
+31-2Lines changed: 31 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,36 @@ Like Python, C-like languages support the core mathematical operations on numeri
16
16
| * | Multiplication|
17
17
| / | Division |
18
18
19
-
Unlike Python there is no exponentiation operator (i.e. no `**`), which requires a function call instead.
19
+
Unlike Python there is no exponentiation operator (i.e. no `**`), which requires making a function call instead.
20
+
21
+
### Operations on mixed types
22
+
```{index} type conversion
23
+
```
24
+
25
+
Remember that in C++, the type of the result of an operation is determined by the types of the operands. If the operands are of different types, the compiler may automatically convert one of them to the type of the other. This is called _type conversion_ or _type casting_. For example, if you divide an integer by a floating point number, the integer will be converted to a float before the division is performed. Generally speaking, the compiler will try to convert the "smaller" type (the one with a smaller range or less precision) to the "larger" type, but you can also force the conversion by using a _type cast_.
26
+
27
+
One key difference from modern Python is that C++ does not automatically convert between integer and floating point types when performing division on integers with the `\` operator. This means that if you divide two integers, the result will be an integer, with any fractional part truncated. To get a floating point result, you must convert one of the operands to a floating point type first.
28
+
29
+
```c++
30
+
31
+
#include<iostream>
32
+
33
+
34
+
intmain() {
35
+
int a = 5;
36
+
int b = 2;
37
+
38
+
// This will print 2
39
+
std::cout << a/b << std::endl;
40
+
41
+
// This will print 2.5
42
+
std::cout << (float)a/b << std::endl;
43
+
44
+
return 0;
45
+
}
46
+
```
47
+
48
+
The code above demonstrates this behaviour, as well as the syntax for casting a variable to a different type . The `(float)` in the second `std::cout` statement is a _type cast_ which converts the integer `a` to a floating point number before the division is performed, refer back to the previous section for more information on type casting.
20
49
21
50
## Logical Operators
22
51
```{index} operators: logical
@@ -36,7 +65,7 @@ Again, as with Python, all the binary logical operators below work in C/C++
36
65
|`a && b`| and |
37
66
|`a \|\| b`| or |
38
67
39
-
In C++ these functions return a `bool` data type which can be equal to `true` or `false` (note the capitalization differs from Python). However, thanks to an implicit type conversion rule, _all_ positive integers evaluate to true and the value zero evaluates to false.
68
+
In C++ these functions return a `bool` data type which can be equal to `true` or `false` (note the capitalization differs from Python). However, thanks to an implicit type conversion rule, _all_ positive integers evaluate to true and the value zero evaluates to false. As in Python, using comparisons with floating point numbers can be tricky due to the way they are stored in memory, and you should be careful when using them to test for equality.
0 commit comments