Hands-on Introduction to the C Programming Language

Post on 28-Nov-2014

300 views 7 download

description

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.

Transcript of Hands-on Introduction to the C Programming Language

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