Skip to content

Commit cdc9ea7

Browse files
committed
differences for PR #29
1 parent edc5c1f commit cdc9ea7

File tree

4 files changed

+355
-1090
lines changed

4 files changed

+355
-1090
lines changed

02-basics.md

Lines changed: 343 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
---
2+
title: 'Basics'
3+
teaching: 35
4+
exercises: 15
5+
---
6+
7+
::::::::::::::::::::::::::::::::::::: questions
8+
9+
- How do we represent and manipulate data in Fortran?
10+
11+
::::::::::::::::::::::::::::::::::::::::::::::::
12+
13+
::::::::::::::::::::::::::::::::::::: objectives
14+
15+
- Understand the different intrinsic data types
16+
- Understand the different intrinsic operators and functions available
17+
18+
::::::::::::::::::::::::::::::::::::::::::::::::
19+
20+
## Fortran data types
21+
22+
Fortran provides the following intrinsic data types:
23+
24+
* numeric types
25+
* `integer`
26+
* `real`
27+
* `complex`
28+
* non-numeric types
29+
* `logical`
30+
* `character`
31+
32+
### Defining numeric variables
33+
34+
The following program declares a variable with each of the three intrinsic
35+
numeric types, and provides an initial value in each case.
36+
```fortran
37+
program example1
38+
39+
integer :: i = 1 ! An integer
40+
real :: a = 2.0 ! A floating point number
41+
complex :: z = (0.0, 1.0) ! A complex number as (real-part, imag-part)
42+
43+
end program example1
44+
```
45+
Initial values are optional, and these values may be changed later within the code.
46+
If a declaration does not specify an initial value, the variable is said to be _undefined_.
47+
48+
### Variable names
49+
50+
The valid Fortran character set for names is `a-z`, `A-Z`, `0-9` and the
51+
underscore `_`. Valid names must begin with a character. The maximum
52+
length of a name is 63 characters (introduced in the F2003 standard) with
53+
no spaces allowed. This includes names for programs, modules, subroutines,
54+
and functions, as well as names for variables.
55+
56+
### The `implicit` statement
57+
58+
By default, variables in Fortran do not need to be declared a specific type, they
59+
can just be used within the code. Variables with names beginning with letters `i-n` are implicitly
60+
of type `integer`, while anything else is of type `real` (unless explicitly declared otherwise).
61+
62+
**This is very bad practice and modern Fortran should not be used in this way.**
63+
64+
The solution to prevent errors involving undeclared variables (usually arising from
65+
typos) is to declare that no names have implicit type via the use of the
66+
```fortran
67+
implicit none
68+
```
69+
statment at the very top of the code.
70+
71+
With this statement inserted, all variable names must be declared explicitly before they
72+
are referenced. It is still common to see variables beginning with `i-n` as integers.
73+
74+
::::::::::::::::::::::::::::::::::::: challenge
75+
76+
## Use `implicit none`
77+
78+
Edit the above example to include an `implicit none` statment, and print out the three variables
79+
80+
:::::::::::::::: solution
81+
82+
```fortran
83+
program solution1
84+
implicit none
85+
86+
integer :: i = 1 ! An integer
87+
real :: a = 2.0 ! A floating point number
88+
complex :: z = (0.0, 1.0) ! A complex number as (real-part, imag-part)
89+
90+
print *, i, a, z
91+
92+
end program solution1
93+
```
94+
Compiling and running this code will give the following output
95+
```
96+
$ ./a.out
97+
1 2.00000000 (0.00000000,1.00000000)
98+
```
99+
100+
:::::::::::::::::::::::::
101+
:::::::::::::::::::::::::::::::::::::::::::::::
102+
103+
### Parameters
104+
105+
In the above example, it is possible to change the values of initialised variables, e.g.
106+
```fortran
107+
program example2
108+
implicit none
109+
110+
real :: a = 2.0
111+
112+
print *, a
113+
114+
a = a + 5.0
115+
116+
print *, a
117+
118+
end program example2
119+
```
120+
This will then give the output:
121+
```
122+
$ ./a.out
123+
2.00000000
124+
7.00000000
125+
```
126+
However, you can also define constant values that cannot change by defining variables using `parameter`.
127+
We are then unable to modify `parameter` variables, e.g.
128+
```fortran
129+
program example3
130+
implicit none
131+
132+
real, parameter :: pi = 3.14159265
133+
134+
pi = pi + 2.0
135+
136+
print *, pi
137+
138+
end program example3
139+
```
140+
When compiling this program, this will give an error similar to the following from the `gfortran` compiler:
141+
```
142+
example3.f90:6:3:
143+
144+
6 | pi = pi + 2.0
145+
| 1
146+
Error: Named constant 'pi' in variable definition context (assignment) at (1)
147+
```
148+
149+
::::::::::::::::::::::::::::::::::::: challenge
150+
151+
## Write a Fortran program to calculate the circumference of a circle
152+
153+
Using the `parameter` statement, write a Fortran program to calculate the circumference of a circle of
154+
radius 3.0.
155+
156+
::::::::::::::::: hint
157+
158+
The cicumference $c$ of a circle can be calculated from the radius $r$ and constant $\pi$ by
159+
160+
$c = 2 \pi r$
161+
162+
::::::::::::::::::::::
163+
164+
:::::::::::::::: solution
165+
166+
```fortran
167+
program solution2
168+
implicit none
169+
170+
real, parameter :: pi = 3.14159265
171+
172+
real :: r=3.0 ! radius of the circle
173+
real :: c ! circumference of the circle
174+
175+
c = 2.0 * pi * r
176+
177+
print *, c
178+
179+
end program solution2
180+
```
181+
Compiling and running this code will give the following output
182+
```
183+
$ ./a.out
184+
18.8495560
185+
```
186+
187+
:::::::::::::::::::::::::
188+
:::::::::::::::::::::::::::::::::::::::::::::::
189+
190+
## Logical variables
191+
192+
Fortran has a `logical` type that has two literal values, True and False, defined by
193+
```fortran
194+
logical :: switch0 = .false.
195+
logical :: switch1 = .true.
196+
```
197+
198+
### Logical operators and expressions
199+
200+
Values can be tested logical operators `.or.`, `.and.` and `.not.` are available, and
201+
these can be used to set the value of logical variables.
202+
203+
The precedence is illustrated by, e.g.,
204+
```fortran
205+
q = i .or. j .and. .not. k ! evaluated as i .or. (j .and. (.not. k))
206+
```
207+
where q, i, j, and k are all logical variables.
208+
209+
The use of parentheses is highly recommended to avoid ambiguity and/or to add clarity.
210+
211+
### Relational operators
212+
213+
To form logical expressions from numeric or other expressions, we require
214+
relational operators. The are two forms in Fortran, illustrated in the table
215+
below. It is recommended that you avoid the older form.
216+
217+
| Relation | Operator | Older form | For |
218+
|--------------------------|----------|------------|------------------|
219+
| Less than | `< ` | `.lt.` | `integer` `real` |
220+
| Less than or equal to | `<=` | `.le.` | `integer` `real` |
221+
| Greater than | `> ` | `.gt.` | `integer` `real` |
222+
| Greater than or equal to | `>=` | `.ge.` | `integer` `real` |
223+
| Equal to | `==` | `.eq.` | `integer` `real` `complex`|
224+
| Not equal to | `/=` | `.neq.` | `integer` `real` `complex`|
225+
226+
### Logical equivalence
227+
228+
Equivalence between two logical expressions or variables is established
229+
via the logical operators `.eqv.` and `.neqv.`.
230+
231+
While some some compilers may allow the use of `==`, this should be avoided.
232+
233+
### Using logical operators
234+
235+
These operators can be used to check and set the values of logical variables, dependent on other variables, e.g.
236+
```fortran
237+
program example4
238+
implicit none
239+
240+
real, parameter :: pi = 3.14159265
241+
logical, parameter :: switch1 = .true.
242+
243+
real :: a=3.0
244+
logical :: test1, test2, test3
245+
246+
test1 = a >= pi ! True if a is greater than or equal to pi
247+
248+
test2 = (.not. test1) ! True if test1 is False, False if test1 is True
249+
250+
test3 = (test2 .eqv. switch1) ! True if test2 is True, False if test2 is False
251+
252+
print *, test1
253+
254+
print *, test2
255+
256+
print *, test3
257+
258+
end program example4
259+
```
260+
Compiling and running this code will give the following output
261+
```
262+
$ ./a.out
263+
F
264+
T
265+
T
266+
```
267+
268+
## Character variables
269+
270+
Character variables are strings that hold zero or more characters. Some examples are:
271+
```fortran
272+
program example5
273+
implicit none
274+
275+
character (len = *), parameter :: string1 = "don't" ! assumed length of 5 characters
276+
character (len = 5) :: string2 = "Don""t" ! 5 characters
277+
character (len = 6) :: string3 = ' don''t' ! blank + 5 characters
278+
279+
end program example5
280+
```
281+
There should be a `len` specifier. Specifying `len = *` means that the length will be assumed
282+
from the length of the string. A space is a valid character in a string.
283+
284+
Strings must be defined within quotation marks, either single, `'`, or double, `"`, beginning
285+
and ending with the same type of mark. To define a quotation mark within a string, either
286+
use one of the alternative type, e.g. `"'"`, or use two of the same type, e.g. `''''`, which
287+
will be intepreted as a single mark within the string.
288+
289+
Strings may be concatenated with the string concatenation operator `//`. For example `string2`
290+
and `string3` could be concatenated into a new variable `string4` by
291+
```fortran
292+
string4 = string2//string3
293+
```
294+
A single character, or a subset of characters, can be extracted via
295+
use of an array-index like notation by defining the start and end characters
296+
to extract, e.g. `string1(1:1)` would extract only the first character from the string
297+
variable `string1`.
298+
299+
::::::::::::::::::::::::::::::::::::: challenge
300+
301+
## Working with strings
302+
303+
Using the above `example5`, concatenate `string2` and `string3` into a new variable `string4`,
304+
and print out the values of all strings. Also, print the third character of `string4`.
305+
306+
:::::::::::::::: solution
307+
308+
```fortran
309+
program solution3
310+
implicit none
311+
312+
character (len = *), parameter :: string1 = "don't" ! 5 characters
313+
character (len = 5) :: string2 = "Don""t" ! 5 characters
314+
character (len = 6) :: string3 = ' don''t' ! blank + 5 characters
315+
character (len = 11) :: string4 ! length of string2+string3
316+
317+
string4 = string2//string3
318+
319+
print *, string1
320+
321+
print *, string2
322+
323+
print *, string3
324+
325+
print *, string4
326+
327+
print *, string4(3:3)
328+
329+
end program solution3
330+
```
331+
Compiling and running this code will give the following output
332+
```
333+
$ ./a.out
334+
don't
335+
Don"t
336+
don't
337+
Don"t don't
338+
n
339+
```
340+
341+
:::::::::::::::::::::::::
342+
:::::::::::::::::::::::::::::::::::::::::::::::
343+

0 commit comments

Comments
 (0)