Introduction to the C Programming Language © V De Florio
HJ-82
Ontwerpen voor de optie multimedia en
signaalverwerking: seminaries
Hands-on Introduction to
the C Programming Language
Vincenzo De Florio
February 2003
V.ppt-1.3
2004-02-10
Introduction to the C Programming Language ( V De Florio)
2
Structure
• Introduction
• First examples
• Variables
• Fundamental data
types
• Loops
• Conditional statements
& other instructions
• The C preprocessor
• Functions
• Variables again
• Operators
• Standard I/O functions
• Derived types
• Pointers and arrays
• Use of pointers
• Type casts &
conversions
• Bitwise operators
• Standard streams, files
• Structures, bitfields,
unions
• LLP
• Data hiding
http://www.esat.kuleuven.ac.be/~deflorio/c/hj82c.prn
Introduction to the C Programming Language ( V De Florio)
3
Introduction
• C and UNIX : success stories.
• C: developed by Dennis Ritchie to port UNIX from a
PDP-7 to a PDP-11
• System programming language
• Most of the UNIX system is in C
Introduction to the C Programming Language ( V De Florio)
4
Introduction
• C is simple:
A small number of simple and powerful
instructions…
…dealing with characters, numbers, addresses
No language facilities for handling complex
objects (strings, lists...)
No language facilities for the I/O, for memory
allocation...
…though those facilities are available as
standard (or user-defined) libraries of functions
Introduction to the C Programming Language ( V De Florio)
5
Introduction
• C is small: Easy to describe, easy to learn
The C compiler is considerably simple, compact-sized, and easy to write
The C data types and control structures often have a direct equivalent in the machine language of many computers. This happens because C was modelled after the machine language of the PDP 11
Hence, while in general the translation from a high level language instruction to machine language is in general one-to-many, the translation from C to machine language is one-to-few
A very simple run-time system: for instance (PDP-11) routines for 32-bit * and /
Introduction to the C Programming Language ( V De Florio)
6
Introduction
• C is portable…
..though, to achieve this, we need to follow some
“rules of portability”
Types have no well-defined size
In OCCAM we have, e.g., int32,
On the contrary, in C we don’t have an a-priori
knowledge of the size of an integer
One can use symbolic constants for this
So called “#define” statements
A large set of standard (-> ported!) libraries exists
for I/O, string manipulation, memory allocation...
Introduction to the C Programming Language ( V De Florio)
7
Introduction
• C provides:
the basic control-flow statements
statement grouping
selective statements
iterative statements
pointers + address arithmetic
Introduction to the C Programming Language ( V De Florio)
8
First examples
main ( )
{
printf(“hello\n”);
}
Function name
Function with
no arguments
Program
starts here...
...and ends
here
Print string
“hello” and
character ‘\n’
Introduction to the C Programming Language ( V De Florio)
9
First examples
• Log into the system
login name
password
• Type in the hello program in file first.c
Activate an editor, e.g., xedit, pico, or vi
for instance xedit first.c
save the file at the end
• Compile the program
cc -o first first.c (or gcc –o first first.c)
• Execute the program
./first
• Modify the program so that
it prints another string / two strings / …
jump to “Compile the program”
Introduction to the C Programming Language ( V De Florio)
10
First Examples
printf
followed by “(“
means
“Call
function printf”
Introduction to the C Programming Language ( V De Florio)
11
First examples
main() { int inf, sup, step;
float fahr, celsius;
inf = 0; sup = 300;
step = 20;
fahr = inf;
while (fahr <= sup) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%4.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}
Integer and
real numbers
Loop
start,
loop
end
Format
string
Introduction to the C Programming Language ( V De Florio)
12
First examples
Introduction to the C Programming Language ( V De Florio)
13
First examples
• Type in the conversion program in file second.c
• Compile the program
• Execute the program
• Modify the program:
Change the format strings
Change steps
Downto vs. To
(5 / 9.0)
(5 / 9)
fahr - 32 vs. fahr - 32.0
fahr += fahr
jump to “Compile the program”
Introduction to the C Programming Language ( V De Florio)
14
Definition of Variables (1)
• To define a variable or a list of variables, one has to
mention: TYPE LIST ;
• For instance: int a, b_b, c2, A;
double f, F=1.3, dimX;
• With LIST one can also initialize variables, like it has been done for F in the above example
• One can define variables only at the beginning of a
compound instruction such as
{ TYPE LIST; … ; INSTRUCTIONS }
Introduction to the C Programming Language ( V De Florio)
15
First examples
main() { int inf, sup, step;
float fahr, celsius;
inf = 0; sup = 300;
step = 20;
fahr = inf;
while (fahr <= sup) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%4.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}
init test
increment
for (fahr = inf; fahr <= sup; fahr += step) {...
Introduction to the C Programming Language ( V De Florio)
16
First examples
• Fahr += step == Fahr = Fahr + step
Fahr++ == Fahr = Fahr + 1
• Compound statements in C:
{ s1; s2; …; sn; }
s1, s2, …, sn;
• Relational operators
<=, <, !=, ==, >, >= ...
Return 0 when false, 1 when true
• “test” is any operation
• 0 = false, non-0 = true
• Both these statements are valid:
while ( x == y ) { …
while ( x = y ) { …
Introduction to the C Programming Language ( V De Florio)
17
First examples
1. Let a be 0
2. Repeat
the loop
while
“a = 0”
is “true” 3. So the
while loop
is simply
ignored!
Introduction to the C Programming Language ( V De Florio)
18
First examples
1. Let a be 1
(returns 1)
2. Repeat
the loop
while
“a = 1”
returns “true” 3. So the
while loop
never ends!
Introduction to the C Programming Language ( V De Florio)
19
First examples
The initial
value of a
is undefined!
Here is -85899…
Here is 0 (cygwin)
Introduction to the C Programming Language ( V De Florio)
20
Fundamental data types
• Four types of integers:
char, short, int, long
• Two types of floating point numbers:
float, double
• Corresponding formats:
%c, %d, %d, %ld
%f, %lf
• Sizes:
sizeof(char) <= sizeof(short) <= sizeof(int) <=
sizeof(long)
sizeof(float) <= sizeof(double)
• Practically speaking:
char==1, short==2, int==2 or 4, long==4
float==4, double==8
Introduction to the C Programming Language ( V De Florio)
21
Fundamental data types
• Check the actual size of type on your workstations
with function sizeof()
Introduction to the C Programming Language ( V De Florio)
22
Fundamental data types
Same result on:
Linux / gcc
SunOS / (g)cc
HP-UX / cc
Win / ms visual c
But this is not
100% guaranteed
on all systems!
Introduction to the C Programming Language ( V De Florio)
23
Type “char”
• A char in C is just an integer
• The only difference between a char and, e.g., an int lies in the number of bytes that are used
• In C, we can write, e.g. int i; char c; i = ‘A’; c = 65; if ( i != c ) printf(“not an “); printf(“ASCII system\n”);
• A char is a small number that, when sent, e.g.,
to the screen, corresponds to a character
• In C there is no difference between
A character
The code of character
Introduction to the C Programming Language ( V De Florio)
24
Type “char”
• Symbols such as ‘A’ are just symbolic constants
• Think of them as a #define statement:
#define ‘A’ 65
#define ‘B’ 66
. . .
• Every time you encounter a
APOSTROPHE CHARACTER APOSTROPHE
you are dealing with a symbolic constant that
defines a small integer, that when printed can be
interpreted as a character
Introduction to the C Programming Language ( V De Florio)
25
Type “char”
• Example
• A = 66;
printf(“ As a number, A is \t%d\n”, A);
printf(“ As a character, A is \t%c\n”, A);
%c ==
“print as a
character”
%d ==
“print as
an integer”
Introduction to the C Programming Language ( V De Florio)
26
Types: some formatting characters
• %d : print as an integer
%c : print as a character
%ld : print as a long
%f : print as a float
%lf : print as a double
Introduction to the C Programming Language ( V De Florio)
27
Types: some formatting characters
Introduction to the C Programming Language ( V De Florio)
28
Types: some formatting characters
Introduction to the C Programming Language ( V De Florio)
29
Types: an interpretation of a same
“substance” – bytes!
(To be explained later on)
The first four bytes of
A are interpreted in
different ways
Introduction to the C Programming Language ( V De Florio)
30
Loops in C
While loops: while ( op1 ) op2;
• No initialisation
• Both op1 and op2 are operations
returning integers
• while op1 is non zero, do op2
• op2 can be a compound instruction, e.g.,
{ op21; op22; … ; op2N }
• relational operations return an integer!
• a <= b is 1 when a<=b and 0
otherwise
Introduction to the C Programming Language ( V De Florio)
31
Loops in C
• Which of these loops are correct? And what do they
mean?
while ( -25 ) a++ ;
while ( read_next_character ( ) ) car = car + 1;
while ( a + 1 ) { a = a + 1; b = 0; }
while ( a ) a = b, b = tmp, tmp = a;
Introduction to the C Programming Language ( V De Florio)
32
Loops in C
While loops: do op2 while ( op1 );
• No initialisation
• Both op1 and op2 are operations
returning integers
• Do op2; then, while op1 is not zero, do
op2 again
• op2 can again be a compound
instruction, e.g., { op21; op22; … ; op2N }
Introduction to the C Programming Language ( V De Florio)
33
Loops in C
• For loops: for ( op1; op2; op3 ) op4;
• Operation op1 is the initialisation
• Operation op2 is the condition
• Operation op3 is the conclusive part
• Operation op4 is the body of the loop,
• Both op1 and op3 can be compound (comma-based!) instructions
• Usually used for iterations, e.g. for (i=0; i<n; i++) { do_that(); }
• Exercise: modify second.c so to change the while into a for.
• Exercise: modify the previous example so to
print the table in inverse order.
Introduction to the C Programming Language ( V De Florio)
34
Loops in C
• Which of these loops are correct? And what do they
mean?
for (;;) a++;
for (; a<5; a++) ;
for ( i=0; i<n; { i++; n--; } ) … /* do something */
for ( i=0, j=n; i<n; i++, j-- ) … /* do sthg */
Introduction to the C Programming Language ( V De Florio)
35
Loops in C
• Loops are an important source of performance for
the compiler and for optimizers
• Some computer architectures and compilers can
exploit them to achieve a very high speed-up
• This is called
“loop level parallelism (LLP) exploitation”
Introduction to the C Programming Language ( V De Florio)
36
Conditional statements
• Statement “if”:
if (condition) action1; else action2;
• “?:”
(condition)? action1 : action2;
• Statement “switch”:
switch(integer expression) {
case value1: op1; break;
case value2: op2; break;
…
case valuen: opn; break;
default: opn+1;
}
Introduction to the C Programming Language ( V De Florio)
37
Other instructions
• break;
• continue;
• goto label;
y:
while (a < b) {
break;
b--;
}
x:
…
a++;
…
break; continue;
goto x;
goto y;
Introduction to the C Programming Language ( V De Florio)
38
The C Preprocessor
• The C compiler was originally composed of four
components:
cpp | cc | as | ld
.c -> .i -> .s -> .o
• Component cpp is the C preprocessor
cpp looks for preprocessor commands (#cmd’s)
#cmd’s start with “#” on column 1
cpp converts a text file f into a text file f’
All the valid “#”-statements are removed and
substituted with C strings or text files
Introduction to the C Programming Language ( V De Florio)
39
The C Preprocessor
• Examples:
• #define BEGIN {
• #define END }
• #define IF if(
• #define THEN )
• #define INT32 long
• #define MAX(A, B) ((A) > (B)? (A):(B))
• #define SQR(x) x * x
• IF SQR(x) == x THEN printf(“x==1\n”);
is translated into
if( x * x ==x ) printf(“x==1\n”);
Dangerous
Introduction to the C Programming Language ( V De Florio)
40
The C Preprocessor
• Inclusion of external files
1. #include <stdio.h>
2. #include “assoc.h”
3. #ifdef … [ #else … ] #endif
4. #ifndef … [ #else … ] #endif
• Differences between 1. and 2.
• Use of 3. and 4.
Introduction to the C Programming Language ( V De Florio)
41
The C Preprocessor
• #include <stdio.h> is equivalent to
• #include “prefix/stdio.h”
• On many UNIX systems, prefix == /usr/include
• /usr/include contains the header files of the C
standard library
stdio.h, string.h, time.h, ctype.h, math.h, …
• A header file is the user interface of a library or a
part of a library
• stdio.h defines the interface to a subset of the C
standard library
• stdio.h interfaces the standard I/O functions and
defines symbols thereof
Introduction to the C Programming Language ( V De Florio)
42
Functions
• Functions are names that points to some memory
location where code has been stored by the
compiler
• They take arguments and return a value of some
type
E.g., double cos(double a);
This is a function prototype, with which we declare a function, called cos, that expects and returns a double
• To call a function, we just name it and pass an
argument to it
cos (3.1415); /* cos (pi) */
Introduction to the C Programming Language ( V De Florio)
43
Functions
• The name of a function is just a number – its
address in the code segment
Introduction to the C Programming Language ( V De Florio)
44
Functions
• Functions can be
Declared
Defined
• A prototype declares a function
“There’s a function that looks like that and that…”
• Defining a function means specifying what the
function shall do
“The function does this and this…”
Memory is allocated in the code segment
Introduction to the C Programming Language ( V De Florio)
45
Functions
• To define a function one has to supply the
compound instruction that it has to execute:
double addd (double a, double b);
double addd (double a, double b)
{
return a + b;
}
Prototype (declaration)
Definition
Introduction to the C Programming Language ( V De Florio)
46
Functions
• Recursion is allowed
• C supports a single-level of functions that
can be compiled separately
Introduction to the C Programming Language ( V De Florio)
47
Functions
• return closes the function and returns an output
value (default: integer) to the caller.
• Arguments are passed by value: this means that the
arguments are copied in temporary variables.
• The only way to let a function modify an argument is
by passing the address of the object to be modified.
• Operator & returns the address of a variable.
Introduction to the C Programming Language ( V De Florio)
48
Functions
• Functions have the following structure:
• [ type ] name ( [ args ] ) {
[ declarations ] [ instructions ] }
• int main() {
int i; int power (int, int);
for (i=0; i<10; ++i)
printf("%d %d\n", i, power(2,i));
}
int power (int x, int n) { int i, p;
for (i = p = 1; i <= n; ++i)
p=p*x;
return (p);
}
Introduction to the C Programming Language ( V De Florio)
49
• Two classes of variables
Dynamically allocated
Statically allocated
• A variable is dynamically allocated when it is local to
a function or a compound instruction and is not
declared as “static”
• Examples
main () {
int i;
for (i=0; i<n; i++) {
int j;
j = i * i;
}
}
Again, on Variables
Automatic
variables
(hold undefined
value)
Introduction to the C Programming Language ( V De Florio)
50
Again, on Variables
• If the variable is an automatic one, then the
initialisation is done each time the variable is
allocated (each time the function in which the
variable resides is called and the corresponding
compound instruction is executed).
Introduction to the C Programming Language ( V De Florio)
51
Again, on Variables
• A variable is defined at compile time when
it is a global variable (I.e., a variable defined outside any
function)
It is a variable defined as “static”
• Example
int fd;
int open(int tmp) {
int j;
static int first;
}
Global
Automatic
Static
Introduction to the C Programming Language ( V De Florio)
52
Again, on Variables
• C is case sensitive: int J; float j; is valid
• The scope of variables is such that a new name
overrides an old one:
int h = 3;
{ int h = 4;
printf(“h == %d\n”, h);
}
printf(“h == %d\n”, h);
Introduction to the C Programming Language ( V De Florio)
53
Operators
• binary +, -, *, /, %
• unary -
• precedences:
• (+,-) (*,/,%) (-) (||)
(&&) (==, !=) (> >= < <=)
• Note:pa opb if opb has higher precedence than opa
Introduction to the C Programming Language ( V De Florio)
54
• Memory model
• Memory is a long array of cells, each ofsize 1 byte
• When I say
{ int a;
what actually happens is
addr = please-os-allocate(4)
now a==(addr, [addr-addr+3])
• When I say
}
what actually happens is
os-please-free(4,addr)
• Automaticly!
• AUTOMATIC variables
Introduction to the C Programming Language ( V De Florio)
55
Operators
• Expressions such as:
i < lim && (c=getchar()) != ’\n’ && c != EOF
do not require extra parentheses:
= !=, hence parentheses are required around
c=getchar().
• Logic clauses are evaluated left-to-right. Evaluation
stops when the truth value of a logic expression is
found.
Introduction to the C Programming Language ( V De Florio)
56
Standard functions for input/output
• Defined in stdio.h
• Require the stdio.h file to be included
• This defines functions such as:
int getchar();
int putchar(int c);
• getchar reads the next character in the standard
input stream or an end-of-file value (EOF)
• getchar returns the character as one byte stored
into a 2-byte or 4-byte integer (an int value)
• Putchar puts on the standard output stream the
character we pass as an argument
Introduction to the C Programming Language ( V De Florio)
57
Standard functions for input/output
void main()
{ char c;
c = getchar();
while ( c != EOF ) {
putchar ( c );
c = getchar();
}
}
Are any
faults
present?
Which
ones?
c is declared
as a char
getchar either
returns a
char or EOF
Introduction to the C Programming Language ( V De Florio)
58
Standard functions for input/output
void main()
{ char c;
c = getchar();
while ( c != EOF ) {
putchar ( c );
c = getchar();
}
}
c is a char
getchar
returns
an int!
This loop
may never be
verified
Introduction to the C Programming Language ( V De Florio)
59
void main()
{ int c;
while ( c = getchar() != EOF ) {
putchar ( c );
}
}
Standard functions for input/output
Are any
faults
present?
Which
ones?
( )
implicit
parentheses OK
If stdin = ‘h’ ‘e’ ‘l’ ‘l’ ‘o’, EOF
what goes to stdout?
Introduction to the C Programming Language ( V De Florio)
60
Exercises
• Exercise: the just seen program can be easily
adapted to work, e.g., as a “word counter” (reports
the number of characters, words, and lines in the
input), or as a filter to remove blanks or tabs, and so
forth
• Input and output can be redirected with < and >.
Pipelines of programs can be built by chaining the
programs with |
Introduction to the C Programming Language ( V De Florio)
61
A memory model for didactics
• Memory can be thought as finite, long array of cells,
each of size 1 byte
0 1 2 3 4 5 6 7 …
• Each cell has a label, called address, and
a content, i.e. the byte stored into it
• Think of a chest of drawers, with a label
on each drawer and possibly something
into it
Introduction to the C Programming Language ( V De Florio)
62
1
2
3
4
Address
Content
A memory model for didactics
Introduction to the C Programming Language ( V De Florio)
63
• The character * has a special meaning
• It refers to the contents of a cell
A memory model for didactics
• For instance:
*(1) ==
This means we’re inspecting the contents
of a cell (we open a drawer and see what’s in it)
Introduction to the C Programming Language ( V De Florio)
64
• The character * has a special meaning
• It refers to the contents of a cell
A memory model for didactics
• For instance:
*(1) =
This means we’re writing new contents
into a cell (we open a drawer and change its contents)
Introduction to the C Programming Language ( V De Florio)
65
Derived types
• The following operators define complex types
derived from the basic types of C: * operator pointer-to,
[] operator vector-of,
() operator function-pointer-to
Introduction to the C Programming Language ( V De Florio)
66
Derived types
• char *p; : p is of type “pointer-to-chars”
• float v[10]; : v is a vector, i.e., a pointer to the
beginning of a memory area allocated by the system and consisting of 10 floats, i.e., v[0], . . . , v[9].
• int getX(); : getX is a pointer to a function
returning an int.
Introduction to the C Programming Language ( V De Florio)
67
Derived types
• Operator [] has higher priority with respect to operator *. This means that int *v[10] means that v is a vector of ten pointers-to-int. Parentheses are necessary to change the meaning: int (*v)[10] means that v is a pointer to a vector of ten integers
• What’s the difference in terms of sizes?
Introduction to the C Programming Language ( V De Florio)
68
Derived types – examples
1. int *pi; pointer to integer;
2. char **argv; pointer to pointer-to-char;
3. float *(fvp)[5]; pointer to vectors-of-5-floats
4. long (*fp)(int); pointer to function reading an
int and returning a long.
Introduction to the C Programming Language ( V De Florio)
69
Derived types
• The address-of (&) operator returns the address of a
variable
char c; char *pc; pc = &c;
• Operator *, applied to a pointer, returns the pointed
object.
char c1 = ’a’; char *p = &c1;
char c2 = *p; /* c2 == ’a’ */
void func(char *s) { printf("bye %s\n", s) }
main() { void (*pfunc)(char*) = func;
*(pfunc)("hello");
}
Introduction to the C Programming Language ( V De Florio)
70
void swap (int a, int b) { int t;
t = a; a = b; b = t;
}
void main() { int a, b;
a = 5, b = 6;
swap (a, b);
printf(“a = %d, b = %d\n”, a, b);
}
Derived types
Are any
faults
present?
Which
ones?
These are
not the same
variables!
Introduction to the C Programming Language ( V De Florio)
71
Derived types
Step Var Address Contents SP int a, b; a 1024 ? 1028
b 1028 ? 1032
a = 5, b = 6; a 1024 5
b 1028 6
swap(a, b)
int a, int b a 1032 5 1036
b 1036 6 1040
int t; t 1040 ? 1044
t = a;a = b;b = t a 1032 6
b 1036 5
t 1040 5
} 1032
a 1024 5
b 1028 6
Introduction to the C Programming Language ( V De Florio)
72
Derived types
• Pointers solve the problem of the lack of “call-by-
reference” in C functions. For instance, in order to
realize a function that swaps its argument, one may
use the following strategy:
int swap(int *a, int *b) { int t;
t = *a, *a = *b, *b = t;
}
• The caller then needs to specify the addresses of
the operands it wants to swap, as in
swap(&i, &j).
Introduction to the C Programming Language ( V De Florio)
73
Derived types
void swap (int* a, int* b) { int t;
t = *a; *a = *b; *b = t;
}
void main() { int a, b;
a = 5, b = 6;
swap (&a, &b);
printf(“a = %d, b = %d\n”, a, b);
}
Introduction to the C Programming Language ( V De Florio)
74
Derived types
Step Var Address Contents SP a = 5, b = 6; a 1024 5 1028
b 1028 6 1032
swap(&a, &b)
int *a, int *b a 1032 1024 1036
b 1036 1028 1040
int t; t 1040 ? 1044
t=*a;*a=*b;*b=t *a 1024 6
*b 1028 5
t 1040 5
} 1032
a 1024 6
b 1028 5
Introduction to the C Programming Language ( V De Florio)
75
Working with the debugger
#include <stdio.h>
main()
{
char *p = NULL;
printf("dereferencing a NULL pointer!\n");
*p = 'A';
printf("done.\n");
}
Big, big mistake…
Introduction to the C Programming Language ( V De Florio)
76
Working with the debugger
Introduction to the C Programming Language ( V De Florio)
77
A useful tool!
Introduction to the C Programming Language ( V De Florio)
78
Working with the debugger
Where did the fault take place?
Introduction to the C Programming Language ( V De Florio)
79
Working with the debugger
Introduction to the C Programming Language ( V De Florio)
80
Commands:
l=list
b=break-
point
r=run
s=step
(also
display var)
Introduction to the C Programming Language ( V De Florio)
81
Command “print”
Introduction to the C Programming Language ( V De Florio)
82
Command “print”
Introduction to the C Programming Language ( V De Florio)
83
Working with the debugger
Introduction to the C Programming Language ( V De Florio)
84
Command
“set”
Introduction to the C Programming Language ( V De Florio)
85
Pointers and arrays
• Note: declaring an array means
1. declaring a pointer
2. allocating memory for the pointed objects.
• The name of the array is indeed a pointer to the first
element of the array. In C lingo, this is
written as vect == &vect[0].
• Exercise: write a program, called report, that reports
the occurrences of each digit char in the input
stream. Use an array of ten elements corresponding
to the ten decimal digits. Produce a histogram at
end-of-input.
Introduction to the C Programming Language ( V De Florio)
86
Pointers and arrays
• Exercise: use two programs,
one that outputs the ten integer numbers that
count the occurrences of each digit char in the
input stream,
the other one that creates a histogram of its input
values.
• Then use a pipeline to hook the two programs:
report2 | histogram
Introduction to the C Programming Language ( V De Florio)
87
Pointers and arrays
• Arrays and pointers are strictly related to each
other: In particular, if int a[10]; then
a == &a[0], a+1 == &a[1], … and so forth.
• In other words, *(a+i) == a[i]
• Any indexed array is equivalent to a pointer plus
some offset, and vice-versa
• Big difference: the array is a constant, i.e., it can never appear on the left of the = sign, as in a = pa; or in a ++;
Introduction to the C Programming Language ( V De Florio)
88
Pointers and arrays
• When passing an array to a function we are indeed
passing the address of its first element; this address
is copied (call-by-value) in a temporary variable.
This variable may be a pointer.
• Example:
char s[7] = "hello!"; /* s is an array */
int i = strlen(s);
int strlen (char *x) { /* x is a pointer */
int n;
for (n=0; *x; x++) /* hence, can be modified */
n++;
return (n);
}
Introduction to the C Programming Language ( V De Florio)
89
Pointers and arrays
• If p is a pointer, p++ lets p point to the next item. It is
the language that takes care of moving p of the right
amount of memory.
• For instance (let us assume an int is 2 bytes and a
double is 8 bytes):
int *p; p == 1222 p+1 == 1224
double *p; p == 5644 p+1 == 5660
and so forth
• In other words: if p is a pointer to an object of type t,
then p+n points n objects further and p-n points n
objects before.
• The actual size of the object doesn’t matter.
Introduction to the C Programming Language ( V De Florio)
90
Pointers to chars
• Strings are available in C as arrays of characters.
Any sentence enclosed between two quotes (“) is an
array of characters ending with character ’\0’
(NULL).
• For instance, "hello" means ’h’, ’e’, ’l’, ’l’, ’o’, 0
• A very common mistake when learning C:
char s1[10] = "Hello ";
char s2[10] = "World";
s1=s2; /* ERROR */
Introduction to the C Programming Language ( V De Florio)
91
Pointers to chars
• As strings are arrays, we can easily pass a string to
a function by passing its name, which points to its
characters:
char a[] = “Kennedy";
printf("Vote %s for president.\n", a);
/* a = &a[0] */
• Variables defined within a function cannot be “seen”
from other functions.
Introduction to the C Programming Language ( V De Florio)
92
Pointers to functions
• Exercise: write a program that uses an array of
pointers-to-function
Input char == number I -> call array[I]
Introduction to the C Programming Language ( V De Florio)
93
Pointers and arrays (2)
• Function strcpy(char *a, char *b);
• Assumption: NULL-terminated strings. Note that
NULL is (int)0, i.e., “false”
• Function strcmp(char *s, char *t): returns a negative
number if s < t, 0 if s == t, a positive number if s > t:
strcmp(char *s, char *t) {
for ( ; *s == *t; s++, t++)
if (*s == ’\0’) return (0);
return (*s - *t);
}
Introduction to the C Programming Language ( V De Florio)
94
Pointers and arrays (2)
• Is this #define OK?
• #define STRCPY(a,b) while (*a++ = *b++) ;
Introduction to the C Programming Language ( V De Florio)
95
Pointers and arrays (2)
• To declare multidimensional arrays one declares
arrays of arrays. For instance,
static int day_of_month[2][13] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
int day_of_year(int day, int month, int year) {
int i, leap =
year%4 == 0 && year%100 != 0 || year%400 == 0;
for (i=1; i<month; i++)
day += day_in_month[leap][i];
return (day);
}
Introduction to the C Programming Language ( V De Florio)
96
Pointers and arrays (2)
• int v[i][j] vs. int v[i,j]
• Entries are stored “by row”: the rightmost index is
the one that varies the most when entries are
referenced in the order they are stored.
• Initialisation: using curly brackets.
• When passing a bidimensional array to a function, it
is mandatory that the number of columns be
specified. For instance:
f(int day_in_month[2][13]), or
f(int day_in_month[][13]), or
f(int (*day_in_month)[13]),
• i.e., pointer to array-of-13 integer entries.
Introduction to the C Programming Language ( V De Florio)
97
Pointers and arrays (2)
• “Entries are stored by rows” means that, e.g.,
int v[100][200];
• is allocated the same way as a
int v[100 × 200];
i.e., as if it were a mono-dimensional array of
20000 int’s.
Introduction to the C Programming Language ( V De Florio)
98
Pointers and arrays (2)
• Fortran stores objects the opposite way with respect
to C:
for (i..) for (j..) a[i][j]
• is equivalent to
DO I.. DO J.. A(J,I)
• Accessing element (i, j) in a n × m matrix means
accessing element k = i × m + j in the associated
mono-dimensional array.
• The same applies for N-dimensional
matrices, N > 2.
Introduction to the C Programming Language ( V De Florio)
99
Pointers and arrays (2)
• Note how, in order to compute value k for an N
dimensional matrix whose dimensions are
(d1, d2, . . . , dN), it is necessary to know the values
d2, . . . , dN:
k = f(d2, . . . , dN).
• Note also that when we need to access sequentially
all the elements of a multidimensional matrix, it is
preferable to use a pointer initialised to the first
entry of the matrix.
Introduction to the C Programming Language ( V De Florio)
100
Pointers and arrays (2)
• #define N 500
#define M 500
main() { int a[N][M];
int i, j, c;
int *pa = & (a[0][0]);
int *pl = & (a[N-1][M-1]);
while (pa < pl) { for (i=0; i<N; i++)
*pa = 0; for (j=0; j<M; j++)
c = *pa + 1; { a[i][j] = 0;
*pa = c; c = a[i][j] +1;
pa++; a[i][j] = c;
} } HP9K 0.7–0.8s 1.2–1.3 s
SUN3 1.1 s 2.4 s
Introduction to the C Programming Language ( V De Florio)
101
Pointers and arrays (2)
• Even when the access is not sequential, it is
possible to exploit specific access patterns (e.g.,
constant stride access).
• An interesting alternative with respect to
multidimensional arrays is by using pointers. For
instance, the computational cost to access
entry (i, j) in a n × m matrix is the one for computing
multiplication (i * m) and addition (i * m + j).
Introduction to the C Programming Language ( V De Florio)
102
Pointers and arrays (2)
• If we change from
int a[100][100];
to
int** a;
and if we properly allocate the 100 pointers in the
row and, for each of them, the memory required for
storing 100 int’s, then
accessing entry (i, j) means executing *((*(a+i)+j))
that has a computational cost of only two additions.
• Furthermore, no dimension information is required
anymore to access any element of the array.
Introduction to the C Programming Language ( V De Florio)
103
Pointers and arrays (2)
• Array of pointers – an example
• char *name_of_month (int n) {
static char *names[] = {
"illegal",
"January",
"February",
. . .
"December“
};
return ((n < 1 || n > 12)? names[0] : names[n] ;
}
Introduction to the C Programming Language ( V De Florio)
104
Pointers and arrays (2)
• Argc and argv: a mechanism that allows a program
to inspect the strings on the command
• line.
• For instance, command echo:
main(int argc, char *argv[]) {
while (--argc > 0)
printf("%s%c", *++argv, (argc>1)?’ ’:’\n’ );
}
• Exercise: compute 2 3 4 + * (in inverse Polish
notation).
• Exercise: write a function that associates user
functions to the command options.
Introduction to the C Programming Language ( V De Florio)
105
Pointers and arrays (2)
• Exercise: write a function that sorts the entries of an
array of integers. Modify the function so that it
requires a pointer-to-function,
int (*confr)(int,int),
to realize sortings in increasing vs. decreasing
order.
• Exercise: “opaque” function, working with pointers to
object of unknown size.
• Exercise (array of functions): design a scanner of a
simple grammar. Tokens must correspond to the
entries in an array of functions.
Introduction to the C Programming Language ( V De Florio)
106
Using pointers
• Using pointers in C may be described as a
connection-oriented service
• One has to open a connection to the memory
service, then use the service (read/write mode),
then disconnect (close) the service
• Example:
int *pi;
pi = malloc(4); /* open:memory-alloc:4 bytes */
*pi = 5; /* use:write-memory:store-in(p,5) */
j = 1 + *pi; /* use:read-memory:get-from(p) */
free(pi); /* close:free-memory-referred-in(p) */
Introduction to the C Programming Language ( V De Florio)
107
Using pointers
1) Definition of a pointer
int *pi; Note: by doing so, one allocates memory for the pointer, not for the pointed
2) Memory allocation pi = malloc(4); or better malloc(sizeof(int)); Note: this is a request for memory allocation.
malloc returns NULL (def:stdio.h) when the request cannot be fulfilled, a value different from NULL when the request can be fulfilled
3) Memory access
*pi = … or … = … *pi …
Note: the valid address returned by malloc points to some memory location where the requested memory resides
Introduction to the C Programming Language ( V De Florio)
108
Using pointers
4) Memory release
free(pi);
Note: the memory pointed to by pi is freed
Note: pi is not “erased”! Still it holds the stale
reference (be careful…)
Introduction to the C Programming Language ( V De Florio)
109
Using pointers
• A common mistake:
char *p;
*p = …
• This is faulty (use-before-connect fault)
• Weird consequences…
Introduction to the C Programming Language ( V De Florio)
110
Using pointers
• A common mistake:
free(p);
*p = *p + 1;
• This is faulty (use-after-disconnect fault)
• Weird consequences…
Introduction to the C Programming Language ( V De Florio)
111
void main() {
int *a, *b;
int c[10], d[10];
a = malloc(10*sizeof(int));
b = calloc(10, sizeof(int));
a = b;
a = c;
d = a;
}
Using pointers
No check
on return
values
The area
pointed by
a is lost
Illegal:
arrays are
const
Introduction to the C Programming Language ( V De Florio)
112
Real-life
experiences
• Commenting a
real life code
• What does this
excerpt do?
• Comment
on the
following:
Courtesy
Siddika
Berna Ors
(COSIC)
Introduction to the C Programming Language ( V De Florio)
113
Real-life
experiences
• Check out this
code
• Check what is
clear and what
is not
• Try to figure
out the
meaning of “?”
and “%”
• What does mp_add do?
Introduction to the C Programming Language ( V De Florio)
114
Real-life experiences
• Check out this code
• Check what is clear and what is not
• Try to figure out the meaning of the program
Introduction to the C Programming Language ( V De Florio)
115
Constants
• scientific notation, e.g., 1.5e3 -> double
• postfix notation, e.g., 145L -> long
• prefix notation:
’0x44’ -> unsigned int, hexadecimal,
’044’ -> unsigned int, octal
• constant char: ’x’ = character x -> char
• special constants, e.g., \n, \t, \0, \\, \" -> char
• “bit patterns”: \ddd, ddd being an octal number.
• string constants, e.g., "string" or "".
Introduction to the C Programming Language ( V De Florio)
116
Type casts and conversions
• Implicit type casts occur when, in expressions,
operands belong to different types.
• Conversions obey the following rules:
char and short int , float double
if an operand is double , the other becomes
double and the result is double
otherwise, if an operand is long , the other
becomes long and the result is a long
otherwise, if an operand is unsigned, the other
one becomes unsigned and the result is
unsigned.
otherwise, operands and result are int .
Introduction to the C Programming Language ( V De Florio)
117
Type casts and conversions
• Converting a string of digits into a number, and vice-
versa, requires specific support. Functions are
available for this, e.g., atoi():
int atoi(char s[]) { int i, n;
n = 0;
for (i=0; s[i]>=’0’ && s[i]<=’9’; ++i)
n=10*n + s[i] -’0’;
return (n);
}
• Note how expression s[i] - ’0’ converts numeric
character s[i] into the digit it represents.
Introduction to the C Programming Language ( V De Florio)
118
Type casts and conversions
• The following function can be used to convert an
uppercase character into its lowercase counterpart
int lower( int c)
{
if (c >=’A’ && c <= ’Z’)
return (c + ’a’ - ’A’);
else
return (c);
}
• Note: this program only works for code tables in
which ’a’ follows ’A’. This is true with ASCII and
false with, e.g., EBCDIC.
Introduction to the C Programming Language ( V De Florio)
119
Type casts and conversions
• Explicit cast:
• The cast operator changes the type of an object.
For instance, the following expression:
celsius = ( (double)5 /9) * (fahr-32.0);
is equivalent to
celsius = (5.0/9.0) * (fahr-32.0);
• Casting is invoked by specifying a type between
parentheses.
Introduction to the C Programming Language ( V De Florio)
120
Increment/decrement operators
• IN C: int i = 0; in Assembly:
i++; DATA segment
i DB 0
. . .
INC i
• Operators such as ++ or -- may have a direct
counterpart in the machine language.
• Operator ++ increments the contents of a variable.
x = n++ is not equivalent to x = ++n.
• Operator -- decrements the contents of a variable.
x = n-- is not equivalent to x = --n.
Introduction to the C Programming Language ( V De Florio)
121
Exercises
• Exercise: function purge(char s[], int c) removes all
occurrences of c from s[].
• Exercise: functions strcpy() and strcat().
Introduction to the C Programming Language ( V De Florio)
122
Exercises
• int strlen (char *p) { int i=0;
while (*p++) i++;
return i;
}
• *p returns the char pointed to by p. *p++ does the
same, but increments the pointer afterwards.
• When does the while loop ends?
• This is an alternative way to write function strlen:
int strlen (char *p) { char *q = p;
while (*p++) ;
return q - p - 1;
}
Introduction to the C Programming Language ( V De Florio)
123
Bitwise operators
• The following six operands can be applied to any
integer expression:
& : bitwise AND
| : bitwise OR
ˆ : bitwise exclusive OR
<< : left shift
>> : right shift
˜ : unary complement.
Introduction to the C Programming Language ( V De Florio)
124
Bitwise operators
• Bitwise AND can be used to set up “masks”, e.g.,
c = n & 0177;
which zeroes all the bits from bit 8 onward.
• Bitwise OR sets bits:
x = x | MASK
sets to 1 the bits that are set in MASK.
• << and >> are respectively arithmetical shifts to the
left and to the right (multiplication re: division by 2).
• Operator ˜ turns each 1 into 0 and vice-versa; it is
used in expressions like, e.g.,
x & ~ 077,
which zeroes the last bits of x. Note that this is
independent of the actual size of x, and hence it is
“more portable” than, e.g., x & 0177700.
Introduction to the C Programming Language ( V De Florio)
125
Bitwise operators
• Let’s consider the following function:
unsigned int
MIDbit (unsigned x, unsigned start, unsigned num)
{
return((x >> (start+1-num)) & ~(~0 << num));
}
• For instance, MIDbit(x, 4, 3) returns the three bits at
position 4, 3, and 2.
• x >> (p+1-n) shifts the bits of interest on the
rightmost position in the word.
• ~ 0 is 11...1;
• n shifts to left lead to 11...1 00..0
• complementing this value we reach 00...0 11..1
n zeroes
n ones
Introduction to the C Programming Language ( V De Florio)
126
Bitwise operators
• Binary operators
+ . / % << >> & ˆ and |
can use notation
e1 op= e2
instead of
e1 = (e1) op (e2).
• Note that x *= y+1 is equivalent to x = x*(y+1).
• An example based on botwise operators follows:
int bitcount(unsigned n) { int b;
for (b=0; n != 0; n >>= 1)
if (n & 01) b++;
return (b);
}
Introduction to the C Programming Language ( V De Florio)
127
The FILE class
• Using files in C may be described as a connection-
oriented service
• One has to open a connection to the file service,
then use the service (read/write mode), then
disconnect (close) the service
• Example:
FILE *pf;
pf = fopen(“readme”, “r”); /* openfile:(readme,rm) */
fprintf(pf, “hi\n”); /* usefile:store-chars(pf,”hi\n”) */
fread(buffer,1,1,pf); /*usefile:read-chars(pf,1,buf) */
fclose (pf); /* closefile(pf) */
Introduction to the C Programming Language ( V De Florio)
128
Structures
• Keyword struct defines a “record.” An example
follows:
struct cd {
char author[30];
int year;
char producer[20];
};
• This is a declaration of a type: no element of this
type has been defined so far. No memory has been
allocated.
• It is now possible to declare objects of type struct cd
struct cd x, y, z;
Introduction to the C Programming Language ( V De Florio)
129
Structures
• The members of a struct can be accessed via the
“dot-operator” (“.”). For instance,
struct cd d;
leap = d.year%4 == 0 &&
d.year%100 != 0 ||
d.year%400 == 0;
• Nesting of structures is allowed:
struct a { struct disco c; } d;
• Access: d.c.year.
• Typedefs.
Introduction to the C Programming Language ( V De Florio)
130
Structures
• A pointer to a structure can be declared, e.g., as
follows:
struct disco *a;
• Access:
(*a).year;
• a->year is equivalent to (*a).year
Introduction to the C Programming Language ( V De Florio)
131
Typedef
• What does, e.g., this statement do?
float complex[2];
• Consider now
typedef float complex[2];
• We have defined a new type
• Example:
complex a;
a[0] = 0.0, a[1] = 1.0;
Introduction to the C Programming Language ( V De Florio)
132
Typedef
• General rule:
consider the definition of a complex object, called x
write “typedef x”
Now x is no more an identifier. It’s a type
Introduction to the C Programming Language ( V De Florio)
133
Typedef
• Example: int func_t (int, int, float); This defines func_t, a pointer-to-function typedef int func_t (int, int, float); This defines a new type, called func_t. Now func_t myF; is equivalent to int myF(int int, float);
Introduction to the C Programming Language ( V De Florio)
134
Typedef
• There are two valid reasons for encouraging the use
of typedef:
parametrizing a program with its types may turn
into semplifying the solution of portability
problems: for instance, typedef short integer;
Moving the code to a machine where the role of
short is played by int we only need to change
one line of code: typedef int integer;
enhancing a program’s readability: a type called
LENGTH brings with its name also a hint at its
usage and meaning within the program.
Introduction to the C Programming Language ( V De Florio)
135
Structures
• Arrays of structures:
• struct key {
char *keyword;
int keycount;
} keytab[100];
• Or
typedef struct key { … } key_t;
and then
key_t keytab[100];
Introduction to the C Programming Language ( V De Florio)
136
Structures
• key_t keytab[100];
• Initialisation:
key_t Keywords[] = {
"break", 0,
"case", 0,
"char", 0,
…
"while", 0
};
• Exercise: Write a program that writes a static arrays
of struct’s to be used as look-up table for another
program.
Introduction to the C Programming Language ( V De Florio)
137
Structures
• Structures can reference themselves:
struct tnode {
char *word; int count;
struct tnode *left;
struct tnode *right;
};
• Another example:
struct nlist {
char *name; char *def;
struct nlist *next;
};
Introduction to the C Programming Language ( V De Florio)
138
Structures
• Exercise:
Write a set of functions dealing with linked lists
Structure the set of functions as a service
Open a connection to the file service, then use
the service (read/write/delete…), then disconnect
(close) the service
Introduction to the C Programming Language ( V De Florio)
139
Bitfield structures
• Flag registers: #define KEYWORD 01
#define EXTERN 02
#define STATIC 04
#define AUTOMT 010
… flags |= EXTERN | STATIC;
… if ( flags & (EXTERN | STATIC) ) ...
• It is possible to store in a same variable, flags, a
series of conditions that can be “turned on” through
a bitwise OR (|) and can be tested via the bitwise
AND (&).
• Clearly the definitions must be powers of 2. Octal
implies unsigned.
Introduction to the C Programming Language ( V De Florio)
140
Bitfield structures
• Structures can be used to specify ag registers via
so-called “bitfields”:
struct {
unsigned is_keyword : 1;
unsigned is_extern : 1;
unsigned is_static : 1;
unsigned is_regist : 1;
} flags;
• Accessing a field: standard way (“.” operator). For
instance: flags.is_extern.
Introduction to the C Programming Language ( V De Florio)
141
Bitfield structures
• Bitfields can be used as lvalues and rvalues as any
other integer variable.
• This means that bitwise OR’s and AND’s are not
necessary:
flags.is extern = 0
if (flags.is extern == 0) ...
Introduction to the C Programming Language ( V De Florio)
142
Bitfield structures
• Bitfields can only be unsigned or int
• Asking the address of a bitfield is illegal
• Bitfields can also be “unnamed,” e.g., for padding
• The standard doesn’t specify if MSB-first or LSB-
first is used.
Introduction to the C Programming Language ( V De Florio)
143
Unions
• An union is a variable having many identifiers
associated to it.
• These identifiers may be of different type and hence
different sizeof’s. Each identifier refer to the same
amount of memory, i.e., as many bytes as the
“largest” type requires. For instance:
union point_x {
char *pc;
float *pf;
double *pd;
long regarded_as_an_int;
} object;
Introduction to the C Programming Language ( V De Florio)
144
Unions
• Variable object has many “aliases”: it can be
regarded as a pointer-to-char, if referred to as
object.pc, or as pointer-to-double (object.pd), or as
a long (object.regarded as an int).
• The amount of memory is always the same, the one
that is enough in order to store the “largest” among
a (char*), a (float*), a (double*), or a (long).
Introduction to the C Programming Language ( V De Florio)
145
Unions
• Typical use of unions:
struct {
int its_type;
union {
int ival;
float fval;
char *pval;
} uval;
} symbol_table[500];
• If we store in symbol table[i].its type a code that
represents the type of object i, then we can set up,
e.g., arrays of objects of different types, or linked
lists of different objects, and so forth.
Introduction to the C Programming Language ( V De Florio)
146
Unions
• A switch on its type is the typical way to execute
diverse actions depending on the nature of the
current object, as it’s done in the following example:
for (i=0;i<500;++i)
switch(symbol_table[i].its_type) {
case ’i’: printf("%d",
symbol_table[i].uval.ival);
break;
…
}
Introduction to the C Programming Language ( V De Florio)
147
Standard libraries
• In C many functions are defined in the so-called
“standard library”, libc.a. A set of headers refer to
the functions and definitions in the standard library.
The header file stdio.h contains the basic functions
and definitions for I/O:
#include <stdio.h>
Introduction to the C Programming Language ( V De Florio)
148
Standard streams
• C and UNIX define three standard I/O streams:
stdin, i.e., the standard input stream, normally given by the characters typed at the keyboard. As in DOS, the redirection character < allows to specify an alternative standard input stream as follows: prog < inputfile
stdout, the standard output stream, normally given by the characters typed onto our display. Character > redirects stdout on an other file, as in prog > outputfile.
stderr, the standard error stream, is again by default our display. Is the stream where the programmer does (should) send the error messages. Can be redirected via 2 >, e.g., prog 2> /dev/null.
Introduction to the C Programming Language ( V De Florio)
149
Pipes
• Besides the stream redirection facilities, UNIX
provides the concept of pipe: if we type
prog1 | prog2
the stdout of prog1 becomes the stdin of prog2.
Introduction to the C Programming Language ( V De Florio)
150
Pipes
TASK 1 TASK 2stdin stdoutstdin stdout
pip
e in pi pe out
int pipeline[2];
pipein = pipeline[STDIN], pipeout = pipeline[STDOUT];
pipe(pipeline);
• pipe() creates an I/O mechanism called “pipe” and returns
two file descriptors, fildes[0] and fildes[1]. The files
associated with fildes[0] and fildes[1] are streams and
are both opened for reading and writing.
• A read from pipeline[0] accesses the data written to
pipeline[1] and a read from pipeline[1] accesses the data
written to pipeline[0] (both on a FIFO basis.)
Introduction to the C Programming Language ( V De Florio)
151
Pipes
• dup2() duplicates an open file descriptor
• dup2(int fildes, int fildes2)
• The dup2() function causes the file descriptor fildes2 to
refer to the same file as fildes. The fildes argument is a
file descriptor referring to an open file.
void main() {
dup2(1,2);
printf(“hello”);
fprintf(stderr, “ world\n”);
}
$ ./a.out
hello world
Introduction to the C Programming Language ( V De Florio)
152
Pipes
TASK 1 TASK 2stdin stdoutstdin stdout
pip
e in pipe o
ut
dup2(pipeout, STDOUT); dup2(pipein, STDIN);
puts(”hello”); gets(msg); // msg is “hello”
h e l l o \0
• STDOUT == 1, STDIN ==0
• Task 1’s stdout is redirected to task 2’s stdin
Introduction to the C Programming Language ( V De Florio)
153
Pipes
• Pipes are also available as FILE*: for instance,
FILE *popen(char *command, const char *type);
int pclose (FILE *stream);
• the popen() function creates a pipe between the
calling program and the command to be executed.
command consists of a shell command line. type is
an I/O mode, either r for reading or w for writing
• The value returned is a stream pointer such that one
can write to the standard input of the command, if
the I/O mode is w, by writing to the file stream; and
one can read from the standard output of the
command, if the I/O mode is r, by reading from the
file stream.
Introduction to the C Programming Language ( V De Florio)
154
Pipes
1. FILE *f = popen(”date”, ”r”);
2. FILE *g=popen(”/bin/sort”, ”w”);
1. with the first one we can, e.g., read the output of
command date.
2. The second one connects to service /bin/sort so to
ask that external service (in this case, to sort a
stream)
Introduction to the C Programming Language ( V De Florio)
155
The UNIX man
• The UNIX command “man” is an important tool
• If you don’t remember how a certain functions is to
be invoked, or what is does, just type
man function
• Try for instance
man printf
man putc
man strcpy
man tolower
Introduction to the C Programming Language ( V De Florio)
156
Makefiles
• A makefile is a script that tells how to compile an application
• It specifies the dependencies among a number of resources (header and C files)
• An example follows: all: myfile.exe
myfile.exe: myfile.o myobj.o
cc –o myfile.exe myfile.o
myobj.o
myfile.o: myfile.c common.h
cc –c myfile.c
myobj.o: myobj.c common.h myobj.h
cc –c myobj.c
Introduction to the C Programming Language ( V De Florio)
157
VLIW
EU EU EU EU
Dec
Instruction Register
Dec Dec Dec
Main instruction
memory
128 bit
Instruction Cache
128 bit
32 bit each
256 decoded bits each
Register file
32 bit each; 8 read ports, 4 write ports
Ca
ch
e/
RA
M
32 bit each; 2 read ports, 1 write port
Main data
memory
32 bit;
1 bi-directional port
Introduction to the C Programming Language ( V De Florio)
158
VLIW
• Properties
Multiple Execution Units: multiple instructions issued in one
clock cycle
Every EU requires 2 operands and delivers one result
every clock cycle: high data memory bandwidth needed
Introduction to the C Programming Language ( V De Florio)
159
VLIW
• Properties
Every EU requires an instruction every clock cycle
Waste of memory and performance when not enough parallel
instructions are available to keep all EUs concurrently busy
Many instruction slots will contain a NOP
Introduction to the C Programming Language ( V De Florio)
160
VLIW
• Properties
Compiler should determine which instructions can be
issued in a single cycle without control dependency conflict
nor data dependency conflict
Deterministic utilization of parallelism: good for hard-real-time
Compile-time analysis of source code: worst case analysis
instead of actual case
Very sophisticated compilers, especially when the EUs are
pipelined! Perform well since early 2000
Introduction to the C Programming Language ( V De Florio)
161
VLIW
• Properties
Compiler should determine which instructions can be
issued in a single cycle without control dependency conflict
nor data dependency conflict
Very difficult to write assembly:
programmer should resolve all control flow conflicts
all data flow conflicts
all pipelining conflicts
and at the same time fit data accesses into the available data
memory bandwidth
and all program accesses into the available program memory
bandwidth
e.g. 2 weeks for a sum-of-products (3 lines of C-code)
All high end DSP processors since 1999 are VLIW
processors (examples: Philips Trimedia -- high end TV, TI
TMS320C6x -- GSM base stations and ISP modem arrays)
Introduction to the C Programming Language ( V De Florio)
162
Loop Level Parallelism
We assume to work with a simple loop such as
for (I=1; I<=1000; I++)
x[I] = X[I] + s;
• Note: each iteration is independent of the others
Very simple case
We can “unroll the loop”
This provides the compiler with more chances to fill
in more slots and execute more instructions in the
same cycle!
Introduction to the C Programming Language ( V De Florio)
163
Loop unrolling: dependencies
• Dealing with data dependencies
• Two classes of methods:
1. Keeping the dependence though avoiding the
hazard (via scheduling)
2. Eliminating a dependence by transforming the code
Introduction to the C Programming Language ( V De Florio)
164
Loop unrolling: 1. dependencies
• Class 2 implies more work
• These are optimization methods used by the
compilers
• Detecting dependencies when only using registers
is easy; the difficulties come from detecting
dependencies in memory:
• For instance 100(R4) and 20(R6) may point to the
same memory location
• Also the opposite situation may take place:
LD 20(R4), R2
…
ADD R3, R1, 20(R4)
• If R4 changes, this is no dependency
Introduction to the C Programming Language ( V De Florio)
165
Loop Level Parallelism
• Let us consider the following loop:
for (I=1; I<=100; I++) {
A[I+1] = A[I] + C[I]; /* S1 */
B[I+1] = B[I] + A[I+1]; /* S2 */ }
• S1 is a loop-carried dependency (LCD):
iteration I+1 is dependent on iteration I:
A’ = f(A)
• S2 is B’ = f(B,A’)
• If a loop has only non-LCD’s, then it is possible to
execute more than one loop iteration in parallel – as
long as the dependencies within each iteration are
not violated
Introduction to the C Programming Language ( V De Florio)
166
Loop Level Parallelism
• What to do in the presence of LCD’s?
• Loop transformations. Example:
for (I=1; I<=100; I++) {
A[I+1] = A[I] + B[I]; /* S1 */
B[I+1] = C[I] + D[I]; /* S2 */ }
• A’ = f(A, B)
B’ = f(C, D)
• Note: no dependencies except LCD’s
Instructions can be swapped!
Introduction to the C Programming Language ( V De Florio)
167
Loop Level Parallelism
• What to do in the presence of LCD’s?
• Loop transformations. Example:
for (I=1; I<=100; I++) {
A[I+1] = A[I] + B[I]; /* S1 */
B[I+1] = C[I] + D[I]; /* S2 */ }
• Note: the flow, i.e.,
A0 B0 A0 B0
C0 D0
C0 D0
A1 B1 can be A1 B1
C1 D1 changed
into C1 D1
A2 B2 A2 B2
C2 D2 . . .
. . .
Introduction to the C Programming Language ( V De Florio)
168
for (i=1; i <= 100; i=i+1) {
A[i] = A[i] + B[i]; /* S1 */
B[i+1] = C[i] + D[i]; /* S2 */
}
becomes
A[1] = A[1] + B[1];
for (i=1; i <= 99; i=i+1) {
B[i+1] = C[i] + D[i];
A[i+1] = A[i+1] + B[i+1];
}
B[101] = C[100] + D[100];
Loop Level Parallelism
Introduction to the C Programming Language ( V De Florio)
169
Loop Level Parallelim
• A’ = f(A, B) B’ = f(C, D)
B’ = f(C, D) A’ = f(A’, B’)
• Now we have dependencies but no more LCD’s!
It is possible to execute more than one loop iteration
in parallel – as long as the dependencies within
each iteration are not violated
Introduction to the C Programming Language ( V De Florio)
170
Loop Level Parallelism
• The original code:
for (x=GB; x<=N-1-GB; ++x)
for (y=GB; y<=M-1-GB; ++y) {
gauss_x_compute[x][y][0]=0;
for (k=-GB; k<=GB; ++k)
gauss_x_compute[x][y][GB+k+1] =
gauss_x_compute[x][y][GB+k] +
image_in[x+k][y]*Gauss[abs(k)];
gauss_x_image[x][y] =
gauss_x_compute[x][y][(2*GB)+1]/tot;
}
is transformed in 3 intermediate substeps.
Introduction to the C Programming Language ( V De Florio)
171
Loop Level Parallelism
• for (x=0; x<N; ++x)
for (y=0; y<M; ++y)
if (x>=GB && x<=N-1-GB &&
y>=GB && y<=M-1-GB) {
gauss_x_compute[x][y][0]=0;
for (k=-GB; k<=GB; ++k) ...
gauss_x_image[x][y]=
gauss_x_compute[x][y][(2*GB)+1]/tot;
}
• In version 1, the loop bounds of the second loop
nest with the horizontal filtering are modified to
match the bounds of the initialisation loop preceding
it
Introduction to the C Programming Language ( V De Florio)
172
Loop Level Parallelism
• In version 2, the initialisation loop is split into two pieces to match the condition of the second loop nest with the horizontal filter.
for (x=0; x<N; ++x)
for (y=0; y<M; ++y)
if (x>=GB && x<=N-1-GB && y>=GB && y<=M-1-GB)
gauss_x_image[x][y]=0;
else
gauss_x_image[x][y]=0;
for (x=0; x<N; ++x)
for (y=0; y<M; ++y)
if (x>=GB && x<=N-1-GB && y>=GB && y<=M-1-GB) {
gauss_x_compute[x][y][0]=0;
for (k=-GB; k<=GB; ++k) ...
gauss_x_image[x][y]= gauss_x_compute[x][y][(2*GB)+1]/tot;
}
Introduction to the C Programming Language ( V De Florio)
173
Loop Level Parallelism
• In version 3, the initialisation loop is then fully merged with the
second loop nest:
for (x=0; x<N; ++x)
for (y=0; y<M; ++y)
if (x>=GB && x<=N-1-GB && y>=GB && y<=M-1-GB) {
gauss_x_image[x][y]=0;
gauss_x_compute[x][y][0]=0;
for (k=-GB; k<=GB; ++k) ...
gauss_x_image[x][y]= gauss_x_compute[x][y][(2*GB)+1]/tot;
}
else
gauss_x_image[x][y]=0;
}
• This gauss_x_compute[x][y][0]=0; statement can then be
worked into the k loop to remove it fully.
Introduction to the C Programming Language ( V De Florio)
174
Performance issues
• How much can the choice of a data structure
influence a property such as locality in sequential
data accesses? In order to evaluate this we run a
simple experiment on a Win2000/Pentium3 PC
Introduction to the C Programming Language ( V De Florio)
175
Performance issues
• Experiment: the following structure:
typedef struct { int a; char b[STRIDE];
} stru_t;
and the following access scheme:
for (i=0; i<itera-1; i++) v[i].a = v[i+1].a + 1;
are compared with the following two data structures:
typedef int stru_ta;
typedef char stru_tb[STRIDE];
and access scheme:
for (i=0; i<itera-1; i++) a[i] = a[i+1] + 1;
Introduction to the C Programming Language ( V De Florio)
176
• Parameters: STRIDE, itera, optimisation level (compiler: cygwin/gcc 2.95.3-5)
•
• The following script is used, where itera goes from 100000 to 2000000 by 100000, and the actual value is an average of 10 run per value of itera:
•
• gcc -DSTRU –O3 stru.c # -O1, -O2, -O3
• #gcc -DSTRU stru.c # or no optimisation at all
• for i in 100000 200000 300000 400000 500000 600000 700000 800000 900000 1000000 1100000 1200000 1300000 1400000 1500000 1600000 1700000 1800000 1900000 2000000 #i==itera
• do
• rm -f $i.stru
• for j in 0 1 2 3 4 5 6 7 8 9
• do
• ( a.exe $i ) >> stru/$i.stru 2>&1
• done`
Introduction to the C Programming Language ( V De Florio)
177
STRIDE == 4 (y axis: usecs; x axis: (x+1)*100000)
Introduction to the C Programming Language ( V De Florio)
178
STRIDE == 8 (y axis: usecs; x axis: (x+1)*100000)
Introduction to the C Programming Language ( V De Florio)
179
STRIDE == 12
Introduction to the C Programming Language ( V De Florio)
180
STRIDE == 16
Introduction to the C Programming Language ( V De Florio)
181
The following pictures plot vertical that
represent the gain in performance between the best “-O3”
cases for different values of STRIDE:
Stride = 4
Introduction to the C Programming Language ( V De Florio)
182
Stride = 16
Introduction to the C Programming Language ( V De Florio)
183
Stride = 32
Introduction to the C Programming Language ( V De Florio)
184
Stride = 64
Introduction to the C Programming Language ( V De Florio)
185
Stride = 128
Introduction to the C Programming Language ( V De Florio)
186
References
• Kernighan & Ritchie,The C programming Language,
Addison-Wesley