Introduction to C Lecture 3: Flow of Control - PowerPoint PPT Presentation

1 / 29
About This Presentation
Title:

Introduction to C Lecture 3: Flow of Control

Description:

As we've said before, when using multiple operators you should use brackets (a) ... Jumping around in code like this rapidly makes it incomprehensible. ... – PowerPoint PPT presentation

Number of Views:26
Avg rating:3.0/5.0
Slides: 30
Provided by: philip150
Category:

less

Transcript and Presenter's Notes

Title: Introduction to C Lecture 3: Flow of Control


1
Introduction to CLecture 3 Flow of Control
  • P. Harris

2
Relational, equality and logical operators
  • Relational operators are
  • lt , gt less, greater than
  • lt, gt less (greater) than or equal to
  • Equality operators are
  • , ! equal (not equal) in a
    question (e.g. if (x 5)...)
  • Logical operators are
  • ! not
  • logical and
  • logical or.
  • As weve said before, when using multiple
    operators you should use brackets (a) to make
    sure your code is clear, and (b) to avoid the
    need to know the order in which these operators
    act.
  • Warning A common error is to use instead of
    this will then set the value instead of
    comparing it...

3
Relational operators
  • The operators gt, lt, lt, gt are all binary they
    take two expressions as operands and yield either
    0 or 1 (int). E.g.
  • a lt 3 yields 1 if true, 0 if false.
  • Note that this is another example of the whole
    expression having a value (which is entirely
    distinct from the value of a).
  • Often a lt b is implemented as a - b lt 0, i.e. b
    is subtracted from a and the answer compared with
    zero.
  •  Consider the expression
  • 3 lt j lt 5
  • which is false, mathematically, if j 7 for
    example. In C, however, it is evaluated as
  • (3 lt j) lt 5 / note left-to-right association /
  • and since 3 lt j is true, this is equivalent to
  • 1 lt 5
  • which is also true. The expression as a whole
    therefore is true, and yields 1. The correct way
    to do the test 3 lt j and j lt 5 is
  • (3 lt j) (j lt 5)
  • and this is true only if both operands of are
    true. (Strictly speaking you could leave out the
    brackets, as lt happens before , but if you put
    the brackets in you dont have to worry about
    it).

4
Relational operators Floating-point numbers
  • Warning
  • When dealing with floating-point numbers, watch
    for rounding error dont ask
  • if (x 0.0) ...
  • if x is floating-point, as some rounding error
    may have left it being a small, but non-zero,
    value instead, try something like
  • eps 1.0e-30
  • if (fabs(x) lt eps) .....

5
Logical operators
  • These are (and), (or) and ! (not). Note
    that you can apply ! to arithmetic expressions
    if the expression is zero, the result will be 1
    if the expression is non-zero, the result will be
    zero. This means that, whereas in ordinary
    logic not (not x) would yield the result x,
    the expression !!5 / equivalent to !(!5)
    /in C yields 1.
  •  
  • Another common mistake is the use of instead of
    the former is a bitwise operation, which we
    will come to in due course.  
  • In evaluating and , the process stops as
    soon as the outcome is known so if, for example,
    you write while (cnt lt 3 (k gt 10)
    / do something... /then, when the
    expression cnt lt 3 is false, k will not be
    incremented, so if you were relying upon that
    happening, you will be in trouble....

6
Exercise
  • Give equivalent simplified logical expressions of
    the following (i.e. get rid of the initial
    not).
  • !(a gt b)
  • !(a lt b c lt d)
  • !(a 1 b 1)
  • !(a lt 1 b lt 2 c lt 3)
  •  

7
Compound statements
  • A group of statements in braces is a compound
    statement when a declaration (e.g. int x) is
    included with it, it is called a block. A
    compound statement is itself a statement. It is
    usual to indent statements within braces, making
    it easier to read e.g.
  • if (a 1)
  • b 2
  • c 3
  • e d c
  • If you use tabs, emacs knows the standard
    indentation rules and will do it for you.

8
Expression statements
  • Expression statements are expressions followed by
    a semicolon these have to be evaluated
    (including side effects) before proceeding to the
    next step. Examples include
  • a b / assignment statement /
  • a b c / legal, but not useful /
  • / empty statement sometimes necessary
    in if constructs etc /
  • printf(d\n, a) / a function call /

9
if and if-else
  • General form is
  • if (expr)
  • statement
  • If expr is nonzero, statement is executed.
    Example
  • if (c )
  • blank_cnt
  • printf(Found another blank.\n)
  •  
  • An obvious extension is if-then-else
  • if (c gt a c lt z)
  • lc_cnt
  • else
  • other_cnt
  • printf(c is not a lowercase letter.\n, c)

Note that you cannot use if (i ! j) i
1 j 2 else i - j The
semicolon makes an empty statement, and the else
then has nowhere to attach to.
10
if-then-else contd
  • Note also that if can itself be part of an if
    statement
  • if (a 1)
  • if (b 2)
  • printf(\n)
  • this is called nesting. An else attaches to
    the nearest if thus
  • if (a 1)
  • if (b 2)
  • printf(\n)
  • else
  • printf(\n)
  • is not correctly formatted the machine will read
    it as
  • if (a 1)
  • if (b 2)
  • printf(\n)
  • else
  • printf(\n)
  •  

11
While loops
  • Format is while (expr) statement
  • Examples
    or
  • Be careful to avoid infinite loops! Consider
  • while (--n)
  • / do something /which would normally
    stop when n reaches zero but if n is negative to
    start with, the loop will be infinite. You could
    instead say
  • while (--n gt 0)
  • / do something /which would guard
    against this possibility.
  • Here we can see an occasion when an empty
    statement might be useful. Consider
  • while ((c getchar()) )
  • / empty statement /
  • which skips blank characters in the input stream.
    Incidentally, the semicolon could go on the same
    line as the while, but putting it on the next
    line makes it clearly visible as an empty
    statement otherwise it will look at first glance
    as though the following lines of code are part of
    the while loop.

while ((c getchar()) ! EOF) / read
from file... /
while (i lt n) factorial i
12
While loops example (cnt_char.c)
  • / Count blanks, digits, letters, newlines and
    others /
  • include ltstdio.hgt
  • int main(void)
  • int blank_cnt 0, c, digit_cnt 0, letter_cnt
    0, nl_cnt 0, other_cnt 0
  •   while (( c getchar() ) ! EOF)
  • if (c ' ')
  • blank_cnt
  • else if (c gt '0' c lt '9')
  • digit_cnt
  • else if (c gt 'a' c lt 'z' c gt 'A' c
    lt 'Z')
  • letter_cnt
  • else if (c '\n')
  • nl_cnt
  • else
  • other_cnt
  • printf("10s10s10s10s10s10s\n\n",
  • "blanks", "digits", "letters", "lines",
    "others", "total")

13
While loops example (cnt_char.c)
  • / Count blanks, digits, letters, newlines and
    others /
  • include ltstdio.hgt
  • int main(void)
  • int blank_cnt 0, c, digit_cnt 0, letter_cnt
    0, nl_cnt 0, other_cnt 0
  •   while (( c getchar() ) ! EOF)
  • if (c ' ')
  • blank_cnt
  • else if (c gt '0' c lt '9')
  • digit_cnt
  • else if (c gt 'a' c lt 'z' c gt 'A' c
    lt 'Z')
  • letter_cnt
  • else if (c '\n')
  • nl_cnt
  • else
  • other_cnt
  • printf("10s10s10s10s10s10s\n\n",
  • "blanks", "digits", "letters", "lines",
    "others", "total")

To execute this program, using its source file
for data, we give the command cnt_char lt
cnt_char.c and we get printed out onto the screen
a table of the numbers of blanks, letters etc.
14
for loops
  • Like while, the for statement is used for
    looping. The construction
  • for (expr1 expr2 expr3)
  • statement
  • next statement
  • is equivalent to
  • expr1
  • while (expr2)
  • statement
  • expr3
  • next statement
  • provided that expr2 is present (and provided that
    there is no continue statement in the body of the
    for loop, in which case expr3 would not be
    evaluated).

15
For loops Example
  • for (i 1, factorial1 i lt n i)
  • factorial i
  • In this case, i is set to 1 initially the loop
    iterates as long as i is lt n and at the end of
    each iteration, i is incremented. This
    construction transparently keeps all control of
    the looping together at the top. Any of the
    statements may be absent, but the two semicolons
    must be present e.g.
  • i 1
  • factorial 1
  • for ( i lt n )
  • factorial i
  • i
  • is equivalent to the above. If the condition
    (i.e. the second expression) is missing, it is
    regarded as being always true. For complete
    brevity, we could write
  • for (i 1, factorial1 i lt n factorial i,
    i)which does the same thing all in one line.

16
Do loops
  • do is like while, except that the condition is
    tested at the bottom of the loop instead of the
    top. Example
  • do
  • printf(Input a postive integer )
  • scanf(d, n)
  • if (error (n lt 0))
  • printf(\n ERROR input was not a positive
    integer!\n)
  • while (error)
  •  
  •       Note the use of the error construction (n
    lt 0) is 0 or 1 then error is set to 0 or 1
    accordingly, but also the expression as a whole
    and if the expression is non-zero, the if test
    is true.
  • A do loop is always carried out at least once, as
    the condition is not tested until the end. They
    are not very common, and it is usual to include
    the body of the loop in even when not needed.

17
Example Fibonacci numbers
  • Fibonacci numbers are defined recursively by
  • f0 0, f1 1, fi1 fi fi-1 for i 1,
    2....
  • The sequence is
  • 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,
    233...
  • They have many interesting uses and properties.
    For example, the sequence of quotients
  • qi fi / fi-1 for i 2, 3....
  • converges to the golden mean (1 sqrt(5))/2.
  • Let us write a program to generate Fibonacci
    numbers and quotients, in file fibonacci.c.

18
Fibonacci numbers contd
  • include ltstdio.hgt / Print Fibonacci numbers
    and quotients /
  • define LIMIT 46
  •  
  • int main(void)
  • long f0 0, f1 1, n, temp
  •  
  • printf("7s19s29s\n7s19s29s\n7s19s29s\n",
  • / headings /
  • " ", "Fibonacci", "Fibonacci",
  • " n ", " number", " quotient",
  • "-------", "---------", "---------")
  • printf("7d19d\n7d19d\n", 0, 0, 1, 1) /
    First 2 cases /
  • for (n 2 n lt LIMIT n)
  • temp f1
  • f1 f0
  • f0 temp
  • printf("7ld19ld29.16f\n", n, f1, (double)
    f1/f0)

19
Fibonacci numbers contd
  • include ltstdio.hgt / Print Fibonacci numbers
    and quotients /
  • define LIMIT 46
  •  
  • int main(void)
  • long f0 0, f1 1, n, temp
  •  
  • printf("7s19s29s\n7s19s29s\n7s19s29s\n",
  • / headings /
  • " ", "Fibonacci", "Fibonacci",
  • " n ", " number", " quotient",
  • "-------", "---------", "---------")
  • printf("7d19d\n7d19d\n", 0, 0, 1, 1) /
    First 2 cases /
  • for (n 2 n lt LIMIT n)
  • temp f1
  • f1 f0
  • f0 temp
  • printf("7ld19ld29.16f\n", n, f1, (double)
    f1/f0)

Variables are declared to be of type long
because some of those printed are too large to be
stored in a 2-byte int (not usually a problem on
modern machines). n doesnt have to be long it
could just as well be int.
20
Fibonacci numbers contd
  • include ltstdio.hgt / Print Fibonacci numbers
    and quotients /
  • define LIMIT 46
  •  
  • int main(void)
  • long f0 0, f1 1, n, temp
  •  
  • printf("7s19s29s\n7s19s29s\n7s19s29s\n",
  • / headings /
  • " ", "Fibonacci", "Fibonacci",
  • " n ", " number", " quotient",
  • "-------", "---------", "---------")
  • printf("7d19d\n7d19d\n", 0, 0, 1, 1) /
    First 2 cases /
  • for (n 2 n lt LIMIT n)
  • temp f1
  • f1 f0
  • f0 temp
  • printf("7ld19ld29.16f\n", n, f1, (double)
    f1/f0)

After printing the heading and the first 2
cases, n is initialized to 2, and the loop runs
until it reaches the predefined LIMIT.
21
Fibonacci numbers contd
  • include ltstdio.hgt / Print Fibonacci numbers
    and quotients /
  • define LIMIT 46
  •  
  • int main(void)
  • long f0 0, f1 1, n, temp
  •  
  • printf("7s19s29s\n7s19s29s\n7s19s29s\n",
  • / headings /
  • " ", "Fibonacci", "Fibonacci",
  • " n ", " number", " quotient",
  • "-------", "---------", "---------")
  • printf("7d19d\n7d19d\n", 0, 0, 1, 1) /
    First 2 cases /
  • for (n 2 n lt LIMIT n)
  • temp f1
  • f1 f0
  • f0 temp
  • printf("7ld19ld29.16f\n", n, f1, (double)
    f1/f0)
  • The sequence of the main loop is
  • 1.  Save f1, the current number, in a temporary.
  • 2.  Add f0 and f1, and store the value in f1, the
    new Fib. number.
  • 3.  Store the temporary in f0, so that f0
    contains the previous number.
  • 4.  Print out, then repeat process.

22
Fibonacci numbers contd
  • include ltstdio.hgt / Print Fibonacci numbers
    and quotients /
  • define LIMIT 46
  •  
  • int main(void)
  • long f0 0, f1 1, n, temp
  •  
  • printf("7s19s29s\n7s19s29s\n7s19s29s\n",
  • / headings /
  • " ", "Fibonacci", "Fibonacci",
  • " n ", " number", " quotient",
  • "-------", "---------", "---------")
  • printf("7d19d\n7d19d\n", 0, 0, 1, 1) /
    First 2 cases /
  • for (n 2 n lt LIMIT n)
  • temp f1
  • f1 f0
  • f0 temp
  • printf("7ld19ld29.16f\n", n, f1, (double)
    f1/f0)

Note the need for temporary storage if
instead we had written f1 f0 f0 f1
then each time through the loop f0 would not
contain the previous number.
23
Fibonacci numbers contd
  • include ltstdio.hgt / Print Fibonacci numbers
    and quotients /
  • define LIMIT 46
  •  
  • int main(void)
  • long f0 0, f1 1, n, temp
  •  
  • printf("7s19s29s\n7s19s29s\n7s19s29s\n",
  • / headings /
  • " ", "Fibonacci", "Fibonacci",
  • " n ", " number", " quotient",
  • "-------", "---------", "---------")
  • printf("7d19d\n7d19d\n", 0, 0, 1, 1) /
    First 2 cases /
  • for (n 2 n lt LIMIT n)
  • temp f1
  • f1 f0
  • f0 temp
  • printf("7ld19ld29.16f\n", n, f1, (double)
    f1/f0)

Because variables are of type long, printf
uses ld (notice l here is lowercase L, not digit
1).
24
Fibonacci numbers contd
  • include ltstdio.hgt / Print Fibonacci numbers
    and quotients /
  • define LIMIT 46
  •  
  • int main(void)
  • long f0 0, f1 1, n, temp
  •  
  • printf("7s19s29s\n7s19s29s\n7s19s29s\n",
  • / headings /
  • " ", "Fibonacci", "Fibonacci",
  • " n ", " number", " quotient",
  • "-------", "---------", "---------")
  • printf("7d19d\n7d19d\n", 0, 0, 1, 1) /
    First 2 cases /
  • for (n 2 n lt LIMIT n)
  • temp f1
  • f1 f0
  • f0 temp
  • printf("7ld19ld29.16f\n", n, f1, ((double)
    f1)/f0)

(double) f1 / f0turns f1 into a
double, and then floating-point (instead of
integer) arithmetic is done. Note 5/4 1 in
integer arithmetic, for example, and 1.25 in
floating-point.
25
goto statements
  • goto causes an unconditional jump to a labelled
    statement. Example
  • if (k lt 0) goto error
  • ....
  • error
  • printf(An error has occurred - goodbye!\n)
  • exit (1)
  •       General rule dont use them! Jumping
    around in code like this rapidly makes it
    incomprehensible. (You might be excused on very
    rare occasions, such as to jump out of a very
    deeply nested inner loop if some test fails but
    it should never be necessary).

26
Break, and continue
  • break causes an exit from the innermost
    enclosing loop
  • while (1)
  • scanf(lf, x)
  • if (x lt 0.0)
  • break / exit loop if x is negative /
  • printf(f\n, sqrt(x))
  • / break jumps to here /
  • continue causes the current iteration of a loop
    to end, and the next to begin immediately
  • for (i 0 i lt TOTAL i)
  • c getchar()
  • if (c gt 0 c lt 9)
  • continue
  • / .... process other characters /
  • / continue transfers to here to begin next
    iteration /
  • continue can only be used in loops, of course.
    Both break and continue should be avoided in
    general, except that break is useful in switch
    statements...

27
switch
  • switch is a generalization of a multiple if-else
    statement. Example
  • switch (c)
  • case a
  • a_cnt
  • break
  • case b
  • case B
  • b_cnt
  • break
  • default
  • other_cnt
  • The controlling expression in () after switch
    (here c) must be of integral type (which includes
    characters). After the expression is evaluated,
    it is matched to each case in turn, and when a
    match is found (or if the default label is
    reached), execution starts at that point.
    Warning the case statements are just labels if
    there is no break statement, execution falls
    through to the statements in the next case.
    This is a common cause of bugs. The default case
    is optional, and is usually of course at the end.
  •  

28
Conditional operator
  • The conditional operator ? is ternary, i.e. it
    takes three arguments. Usage
  • expr1 ? expr2 expr3
  • If expr1 is true, then expr2 is evaluated, and
    that is the value of the statement as a whole.
    If expr1 is false, then expr3 is evaluated, and
    that is the value of the statement as a whole.
  • Thus, this can do the work of an if-else
    statement. Example
  • if (y lt limit)
  • x z1
  • else
  • x z-1
  • can be rewritten as
  • x (y lt limit) ? z1 z-1
  •  

29
For your homework
  • Please make sure code is in your lect2, lect3
    etc directory. If you have problems with it,
    please ask me
  • Please remember to hand in a hard copy to my
    pigeonhole by 5 pm each Weds
Write a Comment
User Comments (0)
About PowerShow.com