Simple and compound statements The -statement -statement comes in two forms:

advertisement
Lecture 2
1
1996-11-26
Lecture 2
2
1996-11-26
Simple and compound statements
The if-statement
The if-statement comes in two forms:
Simple statements:
if (expression)
statement
• expression;
• Various ‘jumps’: break, goto,
continue, return.
or
if (expression)
statement
else
statement
E.g.:
k = a * p + 3;
printf("k = %d\n", k);
1 + 2;
;
E.g.:
if (n > 0)
n--;
else {
printf("!\n");
n = 100;
}
Compound statements:
{
declarations
statements
}
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
3
1996-11-26
Lecture 2
4
1996-11-26
The if-statement (cont).
if (c == ’a’) {
...
} else if (c == ’b’) {
...
} else if (c == ’c’) {
...
} else {
...
}
What happens below? Assume i = 0 and
consider both the case decrement = 0 and
decrement = 1.
if (decrement)
if (i > 0)
i--;
else
i++;
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
The switch-statement
The switch-statement is similar to case in
Pascal:
switch (expression) {
case label1:
statements
case label2:
statements
...
default:
statements
}
Note:
• expression of some integer type.
• Each label must be a constant.
• Fall through! Explicit breaks needed!
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
5
1996-11-26
Lecture 2
6
1996-11-26
The switch-statement (cont.)
The while and do statements
Example:
Syntax:
switch (c) {
case ’a’:
i++;
break;
case ’ ’:
case ’\t’:
case ’\n’:
blank = 1;
break;
default:
j++;
break;
}
while (expression)
statement
do
statement
while (expression);
Example:
int fac(int n)
{
int f, i;
f = i = 1;
while (++i <= n)
f *= i;
}
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
7
1996-11-26
Lecture 2
8
1996-11-26
The for-statement
Very common. Syntax:
for (exp1; exp2; exp3)
statement
Equivalent to:
exp1;
while (exp2) {
statement
exp3;
}
Examples.
for (;;) printf("Hello!\n");
s = 0;
for (i = 1; i <= 10; i++)
s += i;
for (s=0, i=1; i<=10; s+=(i++));
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Function definition using prototypes
The general form of a function definition:
type name(formal args)
{
local vars
code
}
where formal args is a list of the form:
type1 arg1, ..., typen argn
An example:
double max(double x, double y)
{
if (x > y)
return x;
return y;
}
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
9
1996-11-26
Lecture 2
10
1996-11-26
Function definition (cont.)
Declaring functions using prototypes
Two special prototypes:
A function declaration looks like:
• No parameters:
type name(void)
{/*body*/}
type name(formal args);
where formal args is a list of the form:
type1 arg1, ..., typen argn, or
type1, ..., typen
• Variable number of parameters:
type name(args, ...)
{/*body*/}
What is the difference?
• A function declaration makes the function
known to the compiler.
As an example, the printf-prototype:
int printf(const char *format,
... )
• A function may be declared more than
once.
Functions without a result (‘procedures’):
• A function definition gives the code for the
function.
void foo(formal args)
{/*body*/}
• A function must be defined exactly once,
later in the same file or externally.
Only return statements of the form return;
are allowed in the body.
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
11
1996-11-26
Lecture 2
12
1996-11-26
Definitions vs. declarations
Old style (K&R) function definitions
and declarations
Generally:
• A declaration specifies what an identifier
stands for.
• A definition is a construction that, in
addition to declaring an identifier, also
reserves space for it and gives its value.
As a rule, always at least declare before use.
Include files (e.g. stdio.h etc.) contain
declarations only. This is vital.
Old style function definition:
type name(arg. names)
arg. decls
{...}
Typical example:
int foo(x, y)
double x;
double y;
{...}
Old style function declaration:
type name();
E.g.
int foo();
No info about number of args or their type!
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
13
1996-11-26
Lecture 2
14
1996-11-26
Calling functions
Storage classes
A function call:
Basic idea: Storage classes determine how and
when storage is allocated, e.g.:
name(actual args.)
Calling a function without arguments:
Suggest that the compiler try to put a variable
in a CPU register:
name()
register int i;
Note: the parentheses are essential.
Tell the compiler that something is defined
elsewhere:
Argument passing is always call-by-value:
• No ‘reference’ arguments.
external double sin(double);
• The same effect is obtained by passing
pointers by value.
Unfortunately, a little complex in practice:
• The exact meaning of a storage class is
context dependent.
Examples:
int foo(float, int);
• Somewhat complicated default
assumptions.
i = foo(1.2, 17);
printf("%d\n", foo(7.77, 42);
(void) printf("%d\n", 42);
• Other uses, such as controlling visibility of
top level symbols.
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
15
1996-11-26
Lecture 2
16
1996-11-26
The storage class auto
For local variables.
• Default for local variables (and formal
arguments). Usually not stated explicitly.
• Storage is automatically allocated and
deallocated (on system stack) when a
block is entered/left.
• Any initialization performed each time.
• A declaration of an auto object is also a
definition.
The storage class extern
Separate compilation makes it necessary to tell
the compiler:
• which symbols that are defined in another
file, i.e. defined externally,
• which top-level symbols should be visible
outside the file, i.e. visible externally.
The storage class extern serves both these
purposes.
• An auto-object must never be accessed
outside of the block in which it is defined.
Example:
int foo(float x, int i)
{ int n = 10, m = i;
...}
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
17
1996-11-26
Lecture 2
18
1996-11-26
The storage class extern (cont.)
The storage class extern (cont.)
Extern function or variable declaration:
Extern function or variable definition:
• Assumed by default for top-level
declarations.
• Only for top-level (global) symbols.
• Global storage allocated, object lives
throughout the entire execution.
• States the type of the object.
• Initialization performed only once.
(Actually, initialized global data comprises
a section of the executable file.)
• Indicates that the object is either
- defined later in the same file, or
- defined in another file (externally).
• Also indicates to the compiler that the
symbol should be externally visible.
• Storage allocated for top-level variable
declaration (i.e the declaration counts as a
definition, implicit initialization to 0) if:
• Assumed by default for top-level
definitions; usually not stated explicitly.
- extern is not stated explicitly,
- no definition is encountered later in the
file.
• Otherwise, no storage is allocated.
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
19
1996-11-26
Lecture 2
20
1996-11-26
The storage class extern (cont.)
The easy option:
• Use extern explicitly only for ‘importing’ things from other ‘modules’.
• Be aware of that global symbols are
visible outside the file, unless you say
otherwise.
Example on extern usage
File foo.c
extern int a;
int foo(int i)
{
return a * i;
}
File main.c
#include <stdio.h>
extern int foo(int);
int a = 10;
main()
{
printf("%d\n", foo(7));
a = 20;
printf("%d\n", foo(7));
}
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
21
1996-11-26
Lecture 2
22
1996-11-26
The storage class static
Constants
For functions and variables:
• Like external in that a static object
is initialized once and lives during the
entire execution.
• Unlike external in that static
objects are not visible externally.
Variables and parameters may be declared as
constants:
const int max = 7;
const char end = ’\0’;
But:
• Not the same thing as const in Pascal.
• Also, can be applied to local variable
definitions (and declarations, which then
count as definitions).
• Really variables that cannot be assigned
to.
• Use #define if you need compile-time
constants (for sizes of arrays etc.).
Example:
static int fie()
{
static int count = 0;
To see the difference:
int foo(int a, int b)
{
const int m = max(a,b);
/* body of function */
return (++count);
}
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
23
1996-11-26
Lecture 2
24
1996-11-26
Strings in C
No real strings in C. Instead:
Basic arrays
Declaration:
• Pointer to a sequence of char.
• Explicit termination by the null character,
’\0’.
T a[N];
The variable a is an array of N elements of the
type T.
Subscripting:
printf("Hello!\n");
a[0], a[1], ..., a[N-1]
No range checks!
is represented as
printf(•);
H
e
l
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
l
o
! \n \0
Arrays may be initialized when declared:
float f[3]
int a[100]
char s[] =
char s[] =
= {0.0, 1.0, 2.0};
= {0};
{’a’,’b’,’c’,’\0’};
"abc";
Default initialization to 0 of static and
extern arrays.
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
25
1996-11-26
Lecture 2
26
1996-11-26
Bubblesort
Basic pointers
#include <stdio.h>
#define N 20
Declaration:
T *ap;
main()
{
int a[N], i, j, temp;
ap can hold a pointer to an object of type T.
Taking the address of a variable of type T by
using & creates a pointer to an object of type T:
for (i = 0; i < N; i++)
scanf("%d", &a[i]);
for (i = 0; i < N-1; i++)
for (j = N-1; j > i; j--)
if (a[j-1] > a[j]) {
temp = a[j-1];
a[j-1] = a[j];
a[j] = temp;
}
for (i = 0; i < N; i++)
printf("%d ", a[i]);
int a, b, *ap = &a, *bp = &b;
char *s = "abc";
a:
b:
}
ap:
bp:
s:
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
a
b
c \0
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
27
1996-11-26
Lecture 2
28
1996-11-26
Basic pointers (cont.)
Call-by-value vs. call-by-reference
Dereferencing pointers:
a)
b1)
b2)
Call-by-value (C or C++):
*ap = 1;
b = *ap + 1;
ap = bp
*ap = *bp;
a
int y = 1;
void foo(int x) {x++}
...
foo(y);
b1
b2
a: 1
a: 1
a: 2
y is still 1 after the call (contents of y copied to
x which is just a local variable).
b: 2
b: 2
b: 2
Call-by-reference (C++):
ap:
ap:
ap:
bp:
bp:
bp:
int y = 1;
void foo(int &x) {x++}
...
foo(y);
y is 2 after the call since the formal argument x
refers to the actual argument y during the call.
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
29
1996-11-26
Lecture 2
30
1996-11-26
‘Call-by-reference’ in C
Exercise 1
Arguments are always passed by value in C.
No concept of ‘reference parameters’. Instead,
pointers are passed explicitly.
Write a loop to reverse an array int a[N],
i.e. swap a[0] and a[N-1], a[1] and
a[N-2], etc.
Write a function that may be used to swap the
contents of two integer variables.
#include <stdio.h>
void foo(int *ap, int *bp)
{
scanf("%d", ap);
*bp = *ap * 2;
}
Then change your code for reversing the array
so that it uses your swap function.
main()
{
int a, b, c;
foo(&a, &b);
scanf("%d", &c);
printf("a*b=%d,c=%d\n",a*b,c);
}
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
31
1996-11-26
Lecture 2
32
1996-11-26
Pointer arithmetic
In C, + and - also work on pointers:
• An integer may be added to/subtracted
from a pointer.
• One pointer may be subtracted from
another.
Bubblesort revisited
Pointer arithmetic is often used to access arrays
by pointer stepping.
#include <stdio.h>
#define N 20
main()
{
int a[N], *ip, *jp, temp;
The basic assumption is that the pointers refer
to elements in some array:
for (ip = &a[0]; ip < &a[N]; ip++)
scanf("%d", ip);
for (ip = &a[0]; ip < &a[N-1]; ip++)
for (jp = &a[N-1]; jp > ip; jp--)
if (*(jp-1) > *jp) {
temp = *(jp-1);
*(jp-1) = *jp;
*jp = temp;
}
for (ip = &a[0]; ip < &a[N]; ip++)
printf("%d ", *ip);
T x[N]
a-2
T *a:
a+3
}
T *b:
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
33
1996-11-26
Lecture 2
34
1996-11-26
The relationship between arrays
and pointers
The relationship between arrays
and pointers (cont.)
Arrays and pointers are not identical!
In C, an ‘equivalence between arrays and
pointers’ in the following sense holds:
char s1[] = "hello";
char *s2 = "world";
s1:
h
e
l
l
An array is, with three exceptions,
converted to a pointer to its first element
when used.
o \0
The exceptions occur when the array is:
s2:
w
o
r
l
d \0
• an argument to sizeof,
• an argument to &,
Assume a typical 32-bit computer
• a literal string used for initialization of a
char array.
sizeof(s1) = ?
sizeof(s2) = ?
In all other cases we have a = &a[0].
Is the following legal C? Why?
Thus, the for-loops earlier could have been
written:
s1 = s2;
s2 = s1;
for (ip = a; ip < &a[N]; ip++)
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
35
1996-11-26
Lecture 2
36
1996-11-26
The relationship between arrays
and pointers (cont.)
Given
char s1[] = "hello";
char *s2 = "world";
Arrays as arguments to functions
It is always a pointer to the first element that is
passed!
void foo(T *a)
{...}
the ‘equivalence’ explains why:
• s1 = s2 is as invalid as 1 = a,
• s2 = s1 is a legal assignment,
• sizeof(s1) = 6.
Moreover, by definition we have:
s1[i] ≡ *(s1 + i)
s2[i] ≡ *(s2 + i)
The equivalence (together with pointer
arithmetic) explains why this works.
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
main()
{
T a[N];
foo(a);
}
Alternative, equivalent ways of declaring foo:
void foo(T a[])
void foo(T a[N])
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
37
1996-11-26
Lecture 2
38
1996-11-26
Arrays as arguments to
functions (cont.)
Exercise 2
Assume a typical 32-bit architecture, and:
What gets printed when foo is called?
char s[5]="abcd", (*cap)[5];
void foo(int a[10])
{
int b[10];
printf("%d, %d\n",
sizeof(a),
sizeof(b));
}
Answer the following:
sizeof(s) = ?
sizeof(cap) = ?
Is cap = s OK?
Is cap = &s OK?
Reading a string:
sizeof(*cap) = ?
char s[20];
scanf("%19s", s);
sizeof(&s) = ?
• s on its own is the address of the array: no
& in this case!
• There must be room for the terminating
’\0’.
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
39
1996-11-26
Solution exercise 1
Loop to reverse an array int a[N]:
int i, temp;
for (i = 0; i < N/2; i++) {
temp = a[i];
a[i] = a[(N-1)-i];
a[(N-1)-i] = temp;
}
Function to swap two integer variables.
void swap(int *a, int *b)
{
int temp;
temp = *a; *a = *b; *b = temp;
}
Rewriting the loop body:
swap(&a[i], &a[(N-1)-i]);
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Is the following legal C? If so, what gets
printed?
printf("%c\n", 5["abcdef"]);
Linköping University
Department of Computer and Information Science
TDDB 01 System Software
Lecture 2
sizeof(*s) = ?
Download