functions kernighan/ritchie: kelley/pohl: chapter 4 chapter 5

52
Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

Upload: gordon-nelson

Post on 01-Jan-2016

235 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

Functions

Kernighan/Ritchie:Kelley/Pohl:

Chapter 4Chapter 5

Page 2: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

222

Functions

The heart of effective problem solving is problem decomposition

In C, this "top-down" approach is implemented using functions

A program consists of one or more files

Each file consists of zero or more functions, exactly one of which is called main()

Page 3: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

333

Functions

In C, a function declaration and a function definition are two different things

A function declaration tells the compiler that a function exists, and what are its parameter types and return type

A function definition is the actual C code that describes what the function does

Page 4: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

444

Lecture Overview

Function definition

Function declaration and invocation

Developing a large program

Storage classes – auto and extern

Storage classes – register and static

Coding standards and obfuscated code

Page 5: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

555

Function Definition

A function has a header and a body:

The first int defines the return type

int factorial (int n) /* header */{ /* body starts here */ int i, product = 1;

for (i = 2; i <= n; ++i) product *= i; return product;}

Page 6: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

666

Function Definition

Both the return type and the parameter list are optional, and may also be void:

If a function definition does not specify the return type, then it is assumed to be int

However, this will cause the compiler to issue a warning

void welcome (void) { printf ("Welcome to this program.\n");}

Page 7: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

777

Functions with No Parameters

We can write the previous header as:

These formats have different meanings: An empty parameter list means that the

parameters are unknown, and tells the compiler not to perform any parameter checks

A void parameter defines explicitly that the function has no parameters, and this will be enforced by the compiler

void welcome()

Page 8: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

888

Functions with No Parameters – Example

1 #include <stdio.h> 2 3 int f (void) { 4 return 7; 5 } 6 7 int main() { 8 printf ("f(): %d\n", f (3)); 9 return 0;10 }

[prompt] > gcc -o vparam vparam.cvparam.c: In function `main':vparam.c:8: error: too many arguments to function `f'

Page 9: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

999

Functions with No Parameters – Example

1 #include <stdio.h> 2 3 int f() { 4 return 7; 5 } 6 7 int main() { 8 printf ("f(): %d\n", f (3)); 9 return 0;10 }

[prompt] > gcc -o vparam vparam.c[prompt] > vparamf(): 7

Page 10: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

101010

The return Statement

The return statement may or may not include an expression

The parentheses around the returned value or expression are optional

Examples:return;return a + 2;return (a * b);

Page 11: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

111111

The return Statement

Returning a value from a non-void function is the responsibility of the programmer:

This will compile (with a warning), but will print out unpredictable results (garbage)

int f() {}

int main() { printf ("%d\n", f()); return 0;}

Page 12: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

121212

Lecture Overview

Function definition

Function declaration and invocation

Developing a large program

Storage classes – auto and extern

Storage classes – register and static

Coding standards and obfuscated code

Page 13: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

131313

Function Declaration

There are several ways to generate function declarations: Explicitly – using a prototype Implicitly – through the function definition Even more implicitly, by function invocation –

if the compiler encounters an unknown function,it assumes a default declaration:

int f();

Page 14: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

141414

Function Prototypes

Functions can be explicitly declared before they are used:

function declarations of this type are called function prototypes

A prototype defines the parameter types and the return type of the function

float maximum (float x, float y);void print_info();

Page 15: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

151515

Function Prototypes

#include <stdio.h>

void print_num (int);

int main() { print_num (5); return 0;}

void print_num (int a) { printf ("The number is: %d\n", a);}

The number is: 5

Page 16: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

161616

Implicit Function Declaration

A function does not need a prototype if it is only used after its definition#include <stdio.h>

void print_num (int a) { printf ("The number is: %d\n", a);}

int main() { print_num (5); return 0;}

Page 17: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

171717

Implicit Function Declaration

If the compiler encounters a previously undefined and undeclared function:

The function is assumed to be defined somewhere else, with the prototype:

int main() { print_num (5); return 0;}

int print_num();

Page 18: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

181818

Function Invocation

Program execution always begins with the main() function Exactly one must exist in any program

Functions are invoked by writing their name and an appropriate list of arguments within parentheses

The returned value of a function may be assigned to a variable, or just ignored

Page 19: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

191919

Functions – Call by Value

In C, arguments to functions are always passed by value

When an expression is passed as an argument, it is first evaluated, and onlythe result is passed to the function

The variables passed as arguments are not changed in the calling environment

Page 20: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

202020

Functions – Call by Value

int main() { int n = 3, sum, compute_sum (int); printf("%d\n", n); /* 3 is printed */ sum = compute_sum (n); printf("%d\n", n); /* 3 is printed */ printf("%d\n", sum); /* 6 is printed */ return 0;}

int compute_sum (int n) { /* sum from 1 to n */ int sum = 0; for ( ; n > 0; n--) /* n is changed */ sum += n; return sum;}

Page 21: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

212121

Lecture Overview

Function definition

Function declaration and invocation

Developing a large program

Storage classes – auto and extern

Storage classes – register and static

Coding standards and obfuscated code

Page 22: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

222222

Developing a Large Program

Typically, a large program is written in a separate directory as a collection of sourcefiles ('.c') and header files ('.h')

Source files contain mostly function definitions

Header files contain function prototypes and various definitions (e.g. constants and types)

Source files include header files as required

Page 23: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

232323

Developing a Large Program – Example

Suppose that we have a '.c' file containing various utilities used by the program:

The accompanying '.h' file is:

#include "util.h"

int mult (int n) { return n * MULT_FACTOR;}

#define MULT_FACTOR 2int mult (int n);

Page 24: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

242424

Developing a Large Program – Example

Any '.c' file that wishes to use these utilities will include the 'util.h' file:#include <stdio.h>#include "util.h"

int main() {

printf ("%d\n", mult (30));

return 0;}

60

Page 25: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

252525

Compiling Multiple Files

The previous program can be compiled using the following command line

The form of include used here tells the compiler to look for the file in the current directory first, and only then search for it in the system directories

gcc -o use_util use_util.c util.c

Page 26: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

262626

Incremental Compilation

Dividing the program into files may speed up compilation after small changes

It is possible to separate the compilation stage from the linkage stage: Compilation turns source code into object code Linkage turns several object files into a single

executable file

Page 27: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

272727

Incremental Compilation

Using the compiler's -c option, object code files can be generated from source files:

This will create a corresponding '.o' file for each '.c' file:

gcc -c use_util.c util.c

use_util.o util.o

ls *.o

Page 28: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

282828

Incremental Compilation

Now, all of the object files can be linked together to create an executable:

If changes have been made only to a single file, '.c' and '.o' files can be mixed together in the link line:

gcc -o use_util use_util.o util.o

gcc -o use_util use_util.c util.o

Page 29: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

292929

Lecture Overview

Function definition

Function declaration and invocation

Developing a large program

Storage classes – auto and extern

Storage classes – register and static

Coding standards and obfuscated code

Page 30: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

303030

Storage Classes

Every variable and function in C has two attributes – its type and its storage class

The four storage classes are: auto extern register static

Page 31: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

313131

The Storage Class auto

Variables declared within function bodies are automatic by default

When a block is entered, the system allocates memory for the automatic variables defined in it

When the block is exited, the system releases the memory that was set aside for the automatic variables

Page 32: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

323232

The Storage Class extern

One method of transmitting information across blocks and functions is to use external variables

When a variable is declared outside a function, storage is permanently assigned to it, and its storage class is extern

An external variable is considered to be global to all functions declared after it

Page 33: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

333333

The Storage Class extern

int global;

void set (int n) { global = n;}

int get() { return global;}

int main() { set (100); printf ("%d\n", get()); return 0;}

Page 34: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

343434

The Storage Class extern

External variables can also be shared across different files

For example, consider the definition of the variable a in this file:

int a = 5;

void inc() { a++;}

Page 35: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

353535

The Storage Class extern

Now, we can use a in another file:

The extern keyword tells the compiler to look for the definition of a elsewhere

extern int a;void inc();

int main() { inc(); printf ("%d\n", a); return 0;}

Page 36: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

363636

Defining and Declaring External Variables

We distinguish between the declaration of an external variable and its definition

The definition causes storage to be set aside (and also serves as a declaration)

There must be only one definition of an external variable among all of the files that make up the source program

int a = 5;

Page 37: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

373737

Defining and Declaring External Variables

A declaration of the variable should appear in any of the files that use it

This declares for the rest of the file that a is an int, but does not actually create it

Initialization of an external variable goes only with the definition

extern int a;

Page 38: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

383838

Using Header Files for External Declarations

Normally, the declarations in the previous example will be contained in a separate header file, and included by the caller

The first file, 'counter.c', will contain:

#include "counter.h"

int a = 5;

void inc() { a++;}

Page 39: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

393939

Using Header Files for External Declarations

The header file 'counter.h', will be:

And the main file will look like this:

extern int a;void inc();

#include "counter.h"

int main() { inc(); printf ("%d\n", a); return 0;}

Page 40: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

404040

Functions

Functions cannot be nested within blocks, and therefore all functions in C have an extern storage class

As we have seen in the previous example, to use inc() defined in a different file, we had to provide a prototype, but the extern declaration was implicit

Page 41: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

414141

Lecture Overview

Function definition

Function declaration and invocation

Developing a large program

Storage classes – auto and extern

Storage classes – register and static

Coding standards and obfuscated code

Page 42: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

424242

The Storage Class register

The storage class register tells the compiler to store specific variables directlyin the CPU's registers:

This is just a recommendation, and the compiler will ignore it if not enough physical variables are available

register int i;

Page 43: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

434343

The Storage Class static

Static variables have two different uses: To allow a local variable to retain its previous

value when the block is reentered To provide a privacy mechanism that limits the

visibility of variables and functions

These should not be confused with the different meanings of static in other languages, such as Java or C++

Page 44: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

444444

Static Local Variables

Normally, when a variable is defined within a function, it is reallocated with every call, and discarded every time the function ends

A static variable is assigned a single memory location before the program starts, and thus retains its value between subsequent calls of the function

Page 45: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

454545

Static Local Variables

#include <stdio.h>

int f() { static int count = 0; return (count++);}

int main() { printf ("%d ", f()); printf ("%d ", f()); printf ("%d \n", f()); return 0;}

0 1 2

Page 46: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

464646

Static External Variables

The second use of static is to restrictthe scope of external variables

Non-static external variables are available throughout the program

Static external variables are only available to functions defined in the same file And out of these, only to those that were defined

after the static declaration

Page 47: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

474747

Static External Variables

#define INITIAL_SEED 17#define MULTIPLIER 25173#define INCREMENT 13849#define MODULUS 65536

static unsigned seed = INITIAL_SEED;

unsigned int random() { seed = (MULTIPLIER * seed + INCREMENT) % MODULUS; return seed;}

double probability() { seed = (MULTIPLIER * seed + INCREMENT) % MODULUS; return ((double)seed / MODULUS);}

Page 48: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

484848

Static Functions

Just as for external variables, applying the static storage class to a function effectively makes that function private Should be applied to definition and to declaration

The function inc() is now available only to other functions in the same file

static void inc() { a++;}

Page 49: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

494949

Lecture Overview

Function definition

Function declaration and invocation

Developing a large program

Storage classes – auto and extern

Storage classes – register and static

Coding standards and obfuscated code

Page 50: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

505050

C Coding Standards

C provides the programmer with the ability to write powerful and compact code

Its syntax imposes very few restrictions, and leaves much room for originality

C compilers will issue an error only when they have no other choice

Thus, it is easy to write obfuscated code

Page 51: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

515151

Obfuscated Code

This tattoo belongs to Thomas Scovell from Auckland, New Zealand

It is a C program thatprints “hello, world!”

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

Page 52: Functions Kernighan/Ritchie: Kelley/Pohl: Chapter 4 Chapter 5

525252

Obfuscated Code

Can you guess what this program does?long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1,12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12,1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12,12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i]){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf("\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char**V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i<25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v,0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock(8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen("stty -cbreak echo stop \023;cat - HI|sort -rn|head -20>/tmp/$$;mv /tmp/$$ HI\;cat HI","w");fprintf(d,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);}