An introduction to the C programming language for the students of the course "HJ-82 Ontwerpen voor de optie multimedia en signaalverwerking: seminaries", taught by the authors at the Catholic University of Leuven.
2. Structure
2
•
•
•
•
•
•
•
•
•
•
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
3
• 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
4
• 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
5
• C is small:
Easy to describe, easy to learn
The C compiler is considerably simple, compactsized, 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 oneto-few
A very simple run-time system: for instance
(PDP-11)
Introduction to the C Programming Language ( V De Florio)
6. Introduction
6
• 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
7
• 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
8
Function with
no arguments
Function name
Program
starts here...
main ( )
{
printf(“hellon”);
}
Print string
“hello” and
character ‘n’
...and ends
here
Introduction to the C Programming Language ( V De Florio)
9. First examples
9
• 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)
13. First examples
13
•
•
•
•
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)
14
• 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
15
main() { int inf, sup, step;
float fahr, celsius;
inf = 0; sup = 300;
init
step = 20;
test
}
fahr = inf;
while (fahr <= sup) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%4.0f %6.1fn", fahr, celsius);
fahr = fahr + step;
}
increment
for (fahr = inf; fahr <= sup; fahr += step) {...
Introduction to the C Programming Language ( V De Florio)
16. First examples
16
• 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
17
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
18
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
19
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
20
• 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
21
• 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
22
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”
23
• 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 systemn”);
• 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”
24
• Symbols such as ‘A’ are just symbolic constants
• Think of them as a #define statement:
#define
#define
...
‘A’
‘B’
65
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”
25
• Example
• A = 66;
printf(“ As a number, A is t%dn”, A);
printf(“ As a character, A is t%cn”, A);
%c ==
“print as a
character”
Introduction to the C Programming Language ( V De Florio)
%d ==
“print as
an integer”
26. Types: some formatting characters
26
• %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
27
Introduction to the C Programming Language ( V De Florio)
28. Types: some formatting characters
28
Introduction to the C Programming Language ( V De Florio)
29. Types: an interpretation of a same
“substance” – bytes!
29
(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
30
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
31
• 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
32
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
33
•
•
•
•
•
•
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 (commabased!) 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
34
• 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
35
• 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
36
• 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
37
• break;
• continue;
• goto label;
goto y;
y:
while (a < b) {
a++;
…
break; continue;
b--;
}
goto x;
x:
…
Introduction to the C Programming Language ( V De Florio)
38. The C Preprocessor
38
• 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
39
•
•
•
•
•
•
•
•
Examples:
#define BEGIN
{
#define END
}
Dangerous
#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==1n”);
is translated into
if( x * x ==x ) printf(“x==1n”);
Introduction to the C Programming Language ( V De Florio)
40. The C Preprocessor
40
•
1.
2.
3.
4.
Inclusion of external files
#include <stdio.h>
#include “assoc.h”
#ifdef … [ #else … ] #endif
#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
41
•
•
•
#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
42
• 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
43
• 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
44
• 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
45
• 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
46
• 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
47
• 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
48
• 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 %dn", 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. Again, on Variables
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
Automatic
main () {
variables
int i;
(hold undefined
for (i=0; i<n; i++) {
int j;
value)
j = i * i;
}
}
Introduction to the C Programming Language ( V De Florio)
50. Again, on Variables
50
• 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
51
• 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
52
• 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 == %dn”, h);
}
printf(“h == %dn”, h);
Introduction to the C Programming Language ( V De Florio)
53. Operators
53
•
•
•
•
binary +, -, *, /, %
unary precedences:
(+,-) (*,/,%) (-) (||)
(&&) (==, !=) (> >= < <=)
• Note:pa opb if opb has higher precedence than opa
Introduction to the C Programming Language ( V De Florio)
54. 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
55
• 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
56
• 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
57
void main()
{ char c;
c is declared
as a char
c = getchar();
while ( c != EOF ) {
putchar ( c );
c = getchar();
}
getchar either
returns a
char or EOF
}
Introduction to the C Programming Language ( V De Florio)
Are any
faults
present?
Which
ones?
58. Standard functions for input/output
58
void main()
{ char c;
c is a char
getchar
returns
c = getchar();
an int!
while ( c != EOF ) {
putchar ( c );
This loop
c = getchar();
may never be
}
verified
}
Introduction to the C Programming Language ( V De Florio)
59. Standard functions for input/output
59
void main()
{ int c;
OK
implicit
parentheses
while ( c = ( getchar() != EOF ) ) {
putchar ( c );
}
Are any
}
faults
present?
If stdin = ‘h’ ‘e’ ‘l’ ‘l’ ‘o’, EOF
Which
what goes to stdout?
ones?
Introduction to the C Programming Language ( V De Florio)
60. Exercises
60
• 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
61
• 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. A memory model for didactics
62
4
Content
3
2
1
Introduction to the C Programming Language ( V De Florio)
Address
63. A memory model for didactics
63
• The character * has a special meaning
• It refers to the contents of a cell
• 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. A memory model for didactics
64
• The character * has a special meaning
• It refers to the contents of a cell
• 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
65
• 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
66
• 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
67
• 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
68
1.
2.
3.
4.
int *pi;
char **argv;
float *(fvp)[5];
long (*fp)(int);
pointer to integer;
pointer to pointer-to-char;
pointer to vectors-of-5-floats
pointer to function reading an
int and returning a long.
Introduction to the C Programming Language ( V De Florio)
69. Derived types
69
• 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 %sn", s) }
main() { void (*pfunc)(char*) = func;
*(pfunc)("hello");
}
Introduction to the C Programming Language ( V De Florio)
70. Derived types
70
void swap (int a, int b) { int t;
t = a; a = b; b = t;
}
These are
not the same
variables!
void main() { int a, b;
a = 5, b = 6;
swap (a, b);
printf(“a = %d, b = %dn”, a, b);
}
Introduction to the C Programming Language ( V De Florio)
Are any
faults
present?
Which
ones?
71. Derived types
71
Step
Var Address Contents
int a, b;
a = 5,
SP
a
b
a
b
b = 6;
swap(a, b)
int a, int b
int t;
t = a;a = b;b = t
1024
1028
1024
1028
?
?
5
6
1028
1032
a
b
t
a
b
t
1032
1036
1040
1032
1036
1040
5
6
?
6
5
5
1036
1040
1044
}
1032
a
b
1024
1028
Introduction to the C Programming Language ( V De Florio)
5
6
72. Derived types
72
• Pointers solve the problem of the lack of “call-byreference” 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
73
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 = %dn”, a, b);
}
Introduction to the C Programming Language ( V De Florio)
74. Derived types
74
Step
a = 5,
Var Address Contents
b = 6;
SP
a
b
swap(&a, &b)
int *a, int *b
int t;
t=*a;*a=*b;*b=t
1024
1028
5
6
1028
1032
a
b
t
*a
*b
t
1032
1036
1040
1024
1028
1040
1024
1028
?
6
5
5
1036
1040
1044
}
1032
a
b
1024
1028
Introduction to the C Programming Language ( V De Florio)
6
5
75. Working with the debugger
75
#include <stdio.h>
main()
Big, big mistake…
{
char *p = NULL;
printf("dereferencing a NULL pointer!n");
*p = 'A';
printf("done.n");
}
Introduction to the C Programming Language ( V De Florio)
76. Working with the debugger
76
Introduction to the C Programming Language ( V De Florio)
85. Pointers and arrays
85
• 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
86
• 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
87
• 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
88
• 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
89
• 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
90
• 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
91
• 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
92
• 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)
93
• 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)
94
• 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)
95
• 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)
96
• 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)
97
• “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)
98
• 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)
99
• 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)
100
• #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) {
*pa = 0;
c = *pa + 1;
*pa = c;
pa++;
}
for (i=0; i<N; i++)
for (j=0; j<M; j++)
{ a[i][j] = 0;
c = a[i][j] +1;
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)
101
• 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)
102
• 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)
103
• 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)
104
• 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)
105
• 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
106
• 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
107
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
108
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
109
• 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
110
• 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. Using pointers
111
void main() {
int *a, *b;
int c[10], d[10];
No check
on return
values
a = malloc(10*sizeof(int));
The area
b = calloc(10, sizeof(int));
pointed by
a = b;
a is lost
a = c;
Illegal:
d = a;
arrays are
}
const
Introduction to the C Programming Language ( V De Florio)
113. Real-life
experiences
113
• 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
114
• 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
115
• 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
116
• 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
117
• Converting a string of digits into a number, and viceversa, 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
118
• 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
119
• 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
120
• IN C:
int i = 0;
i++;
in Assembly:
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
121
• 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
122
• 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
123
• 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
124
• 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
125
• 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 zeroes
• n shifts to left lead to 11...1 00..0
n ones
• complementing this value we reach 00...0 11..1
Introduction to the C Programming Language ( V De Florio)
126. Bitwise operators
126
• 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
127
• Using files in C may be described as a connectionoriented 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, “hin”); /* usefile:store-chars(pf,”hin”) */
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
128
• 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
129
• 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
130
• 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
131
• 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
132
• 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
133
• 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
134
• 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
135
• 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
136
• 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
137
• 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
138
• 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
139
• 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
140
• 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
141
• 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
142
•
•
•
•
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 LSBfirst is used.
Introduction to the C Programming Language ( V De Florio)
143. Unions
143
• 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
144
• 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
145
• 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
146
• 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
147
• 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
148
• 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
149
• 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
150
• 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.)
int pipeline[2];
pipein = pipeline[STDIN], pipeout = pipeline[STDOUT];
pipe(pipeline);
stdin
TASK 2
pip e
ut
TASK 1
stdout
eo
stdin
in
pi p
Introduction to the C Programming Language ( V De Florio)
stdout
151. Pipes
151
• 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, “ worldn”);
}
$ ./a.out
hello world
Introduction to the C Programming Language ( V De Florio)
152. Pipes
152
• STDOUT == 1, STDIN ==0
• Task 1’s stdout is redirected to task 2’s stdin
dup2(pipeout, STDOUT);
TASK 1
stdout
stdin
pip
h e l l o 0
e ou
p ip e
in
puts(”hello”);
TASK 2
stdout
t
stdin
dup2(pipein, STDIN);
gets(msg); // msg is “hello”
Introduction to the C Programming Language ( V De Florio)
153. Pipes
153
• 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
154
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
155
• 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
156
• 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
Main instruction
memory
157
128 bit
Instruction Cache
128 bit
Instruction Register
32 bit each
Dec
Dec
Dec
Dec
256 decoded bits each
EU
EU
EU
Register file
EU
32 bit each; 8 read ports, 4 write ports
32 bit each; 2 read ports, 1 write port
Cache/
RAM
32 bit;
1 bi-directional port
Main data
memory
Introduction to the C Programming Language ( V De Florio)
158. VLIW
158
• 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
159
• 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
160
• 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
161
• 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
162
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
163
• 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
164
• 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
165
• 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
166
• 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
167
• 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. Loop Level Parallelism
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];
Introduction to the C Programming Language ( V De Florio)
169. Loop Level Parallelim
169
• 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
170
• 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
171
• 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
172
• 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
173
• 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
174
• 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
175
• 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. 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
Introduction to the C Programming Language ( V De Florio)
177. 177
STRIDE == 4 (y axis: usecs; x axis: (x+1)*100000)
Introduction to the C Programming Language ( V De Florio)
178. 178
STRIDE == 8 (y axis: usecs; x axis: (x+1)*100000)
Introduction to the C Programming Language ( V De Florio)
181. 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)