Programming Language C Functions and Program Structure 主講人:虞台文

Preview:

Citation preview

Programming Language CFunctions and Program Structure

主講人:虞台文

Content Console-Mode knowledge Basic of Functions Return Types External Variables Header Files Static Variables Recursion

Programming Language CFunctions and Program Structure

Console-Mode knowledge

Setting Environment Variables

Setting Command Paths

Appending Your Command Paths

Appending Your Command Paths

......;G:\Users\twyu\MyUtilities\

Running Console-Mode Applications

Programming Language CControl Flow

Basic of Functions

Why Functions?

Functions represent computing modules upon which you can design large software programs:– facilitate program decomposition– hide irrelevant details– make programs easy to read and

understand– easy to maintain– most importantly, easy to debug

Example: Unix grep

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

grepExample.txt

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

grep "ould" grepExample.txt

Ah Love! could you and I with Fate conspireWould not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Ah Love! could you and I with Fate conspireWould not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Example: Unix grep

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

grepExample.txt

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

grep "ould" grepExample.txt

Ah Love! could you and I with Fate conspireWould not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Ah Love! could you and I with Fate conspireWould not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Pseudo Code The Idea to Fulfill the Task

while (there's another line)

if (the line contains the pattern)

print it

Pseudo Code The Idea to Fulfill the Task

while (there's another line)

if (the line contains the pattern)

print it

How?Define functions to mind the

detail.

How?Define functions to mind the

detail.

Pseudo Code The Idea to Fulfill the Task

while (there's another line)

if (the line contains the pattern)

print it

int getline(char line[], int max)

int strindex(char source[], char searchfor[])

Pseudo Code The Idea to Fulfill the Task

while (there's another line)

if (the line contains the pattern)

print it

int getline(char line[], int max)

int strindex(char source[], char searchfor[])

Return typeReturn type Function name

Function name

Argument declarations

Argument declarations

Function Definition

return-type function-name(argument declarations)

{

declarations

statements

}

Function body (the detail)

Example: MyGrep#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int max);int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */main(){ char line[MAXLINE]; int found = 0;

while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;}. . . . . . . . . . . . . . . . . .

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int max);int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */main(){ char line[MAXLINE]; int found = 0;

while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;}. . . . . . . . . . . . . . . . . .

while (there's another line)

if (the line contains the pattern)

print it

Example: MyGrep#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int max);int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */main(){ char line[MAXLINE]; int found = 0;

while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;}. . . . . . . . . . . . . . . . . .

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int max);int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */main(){ char line[MAXLINE]; int found = 0;

while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;}. . . . . . . . . . . . . . . . . .

while (there's another line)

if (the line contains the pattern)

print it

forward references

return information to OS

Batch Files

Example: MyGrep

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!

Example: MyGrep#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int max);int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */main(){ char line[MAXLINE]; int found = 0;

while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;}. . . . . . . . . . . . . . . . . .

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int max);int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */main(){ char line[MAXLINE]; int found = 0;

while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;}. . . . . . . . . . . . . . . . . .

while (there's another line)

if (the line contains the pattern)

print it

where to get these functions?

return information to OS

You have several choices:• Write by yourself in the same file.• Write by yourself but in difference files.• Use a library function if available• .................................

You have several choices:• Write by yourself in the same file.• Write by yourself but in difference files.• Use a library function if available• .................................

Example: MyGrep#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int max);int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */main(){ char line[MAXLINE]; int found = 0;

while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;}. . . . . . . . . . . . . . . . . .

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int max);int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */main(){ char line[MAXLINE]; int found = 0;

while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;}. . . . . . . . . . . . . . . . . .

while (there's another line)

if (the line contains the pattern)

print it

where to get these functions?

return information to OS

You have several choices:• Write by yourself in the same file.• Write by yourself but in difference files.• Use a library function if available• .................................

You have several choices:• Write by yourself in the same file.• Write by yourself but in difference files.• Use a library function if available• .................................

Example: getline

/* getline: get line into s return length *//* return EOF if reach file end */int getline(char s[], int lim){ int c, i;

i = 0; while (--lim > 0 && (c=getchar()) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i;}

/* getline: get line into s return length *//* return EOF if reach file end */int getline(char s[], int lim){ int c, i;

i = 0; while (--lim > 0 && (c=getchar()) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i;}

Mind the detail by the function writer.

Example: strindex

/* strindex: return index of t in s, -1 if none */

int strindex(char s[], char t[]){ int i, j, k;

for (i = 0; s[i] != '\0'; i++) { for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++) ; if (k > 0 && t[k] == '\0') return i; } return -1;}

/* strindex: return index of t in s, -1 if none */

int strindex(char s[], char t[]){ int i, j, k;

for (i = 0; s[i] != '\0'; i++) { for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++) ; if (k > 0 && t[k] == '\0') return i; } return -1;}

Mind the detail by the function writer.

Return Statement

/* strindex: return index of t in s, -1 if none */

int strindex(char s[], char t[]){ int i, j, k;

for (i = 0; s[i] != '\0'; i++) { for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++) ; if (k > 0 && t[k] == '\0') return i; } return -1;}

/* strindex: return index of t in s, -1 if none */

int strindex(char s[], char t[]){ int i, j, k;

for (i = 0; s[i] != '\0'; i++) { for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++) ; if (k > 0 && t[k] == '\0') return i; } return -1;}

Return Statement

return expressionConversion will be

performed if necessary

More on Return Statement

The return statement terminates the execution of the function body and passes control to the caller.

The caller is free to ignore the returned value.

Missing return statement, though improper in some cases, is not illegal– In this case, result is unpredictable

More on Return Statement

#include <stdio.h>

int fun1(int), fun2(int), fun3(int), fun4(int);

int main(){ int m, n, o, p, q; fun1(3. 0); /* caller ignores the return value */ m = fun1(2.0); /* m = 4 parameter converted to int before calling */ n = fun2(2); /* n = 1 */ o = fun2(-2); /* o = ? */ p = fun3(2); /* p = ? */ q = fun4(2); /* q = ? */ printf("m=%d\nn=%d\no=%d\np=%d\nq=%d\n", m, n, o, p, q); /* main don’t return any value */}

int fun1(int a){ return 2.0 * a; /* converted to integer before return */}

int fun2(int a){ if(a>0) return 1; /* return nothing when a <= 0 */}

int fun3(int a){ return; /* missing expression */}

int fun4(int a){ /* do nothing */}

#include <stdio.h>

int fun1(int), fun2(int), fun3(int), fun4(int);

int main(){ int m, n, o, p, q; fun1(3. 0); /* caller ignores the return value */ m = fun1(2.0); /* m = 4 parameter converted to int before calling */ n = fun2(2); /* n = 1 */ o = fun2(-2); /* o = ? */ p = fun3(2); /* p = ? */ q = fun4(2); /* q = ? */ printf("m=%d\nn=%d\no=%d\np=%d\nq=%d\n", m, n, o, p, q); /* main don’t return any value */}

int fun1(int a){ return 2.0 * a; /* converted to integer before return */}

int fun2(int a){ if(a>0) return 1; /* return nothing when a <= 0 */}

int fun3(int a){ return; /* missing expression */}

int fun4(int a){ /* do nothing */}

More on Return Statement

#include <stdio.h>

int fun1(int), fun2(int), fun3(int), fun4(int);

int main(){ int m, n, o, p, q; fun1(3. 0); /* caller ignores the return value */ m = fun1(2.0); /* m = 4 parameter converted to int before calling */ n = fun2(2); /* n = 1 */ o = fun2(-2); /* o = ? */ p = fun3(2); /* p = ? */ q = fun4(2); /* q = ? */ printf("m=%d\nn=%d\no=%d\np=%d\nq=%d\n", m, n, o, p, q); /* main don’t return any value */}

int fun1(int a){ return 2.0 * a; /* converted to integer before return */}

int fun2(int a){ if(a>0) return 1; /* return nothing when a <= 0 */}

int fun3(int a){ return; /* missing expression */}

int fun4(int a){ /* do nothing */}

#include <stdio.h>

int fun1(int), fun2(int), fun3(int), fun4(int);

int main(){ int m, n, o, p, q; fun1(3. 0); /* caller ignores the return value */ m = fun1(2.0); /* m = 4 parameter converted to int before calling */ n = fun2(2); /* n = 1 */ o = fun2(-2); /* o = ? */ p = fun3(2); /* p = ? */ q = fun4(2); /* q = ? */ printf("m=%d\nn=%d\no=%d\np=%d\nq=%d\n", m, n, o, p, q); /* main don’t return any value */}

int fun1(int a){ return 2.0 * a; /* converted to integer before return */}

int fun2(int a){ if(a>0) return 1; /* return nothing when a <= 0 */}

int fun3(int a){ return; /* missing expression */}

int fun4(int a){ /* do nothing */}

Console Multiple Source Files

Console Multiple Source Files

...>cl Mygrep.c Getline.c StrIndex.c

Console Multiple Source Files

IDE Multiple Source Files

Exercises

1. Write the function strindex(s,t) which returns the position of the rightmost occurrence of t in s, or -1 if there is none, and use the new strindex function to build mygrep project both in console mode and IDE mode.

Programming Language CFunctions and Program Structure

Return Types

Function Definition

return-type function-name(argument declarations)

{

declarations

statements

}

Function body (the detail)

Return Types

return-type function-name(argument declarations)

{

declarations

statements

}

Function body (the detail)

return-type

The return-type must be specified if the function doesn’t return an integer or returns nothing.

The return-type must be specified if the function doesn’t return an integer or returns nothing.

Default Return Type

function-name(argument declarations)

{

declarations

statements

}

Function body (the detail)

If the type is not specified, it is assumed to be int by default.

If the type is not specified, it is assumed to be int by default.

void Return Type

void function-name(argument declarations)

{

declarations

statements

}

Function body (the detail)

The type specifier void is used to declare functions that are not intended to return values.Such functions usually do something by side-effects.

The type specifier void is used to declare functions that are not intended to return values.Such functions usually do something by side-effects.

Example: Function Returning Integer

power(int m, int n){ int i, product=1; for(i=1; i<=n; ++i) product = m; return (product);}

power(int m, int n){ int i, product=1; for(i=1; i<=n; ++i) product = m; return (product);}

int power(int m, int n){ int i, product=1; for(i=1; i<=n; ++i) product = m; return (product);}

int power(int m, int n){ int i, product=1; for(i=1; i<=n; ++i) product = m; return (product);}

Example: Function Returning Integers

Forward-reference declarations can be absent for functions that return int.

Build Succeeded

Example: Function Returning Integers

Forward-reference declarations can be absent for functions that return int.

Build failed

More on Functions Returning Integers

The return value can be treated as– a measure, e.g., strlen– a measure with error indication, e.g., getchar– Boolean value– result Code– error level

Functions Returning Non-Integers

double abs(double x){ if (x >= 0.0) return (x); else return (-x);}

double abs(double x){ if (x >= 0.0) return (x); else return (-x);}

• Return type must be specified.• Forward reference needed before being used

• Return type must be specified.• Forward reference needed before being used

Example: atof#include <ctype.h>

/* atof: convert string s to double */double atof(char s[]){ double val, power; int i, sign;

for (i = 0; isspace(s[i]); i++) ; /* skip white space */ sign = (s[i] == '-') ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; for (val = 0.0; isdigit(s[i]); i++) val = 10.0 * val + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = 10.0 * val + (s[i] - '0'); power *= 10; } return sign * val / power;}

#include <ctype.h>

/* atof: convert string s to double */double atof(char s[]){ double val, power; int i, sign;

for (i = 0; isspace(s[i]); i++) ; /* skip white space */ sign = (s[i] == '-') ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; for (val = 0.0; isdigit(s[i]); i++) val = 10.0 * val + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = 10.0 * val + (s[i] - '0'); power *= 10; } return sign * val / power;}

Example: atoi#include <ctype.h>

/* atof: convert string s to double */double atof(char s[]){ double val, power; int i, sign;

for (i = 0; isspace(s[i]); i++) ; /* skip white space */ sign = (s[i] == '-') ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; for (val = 0.0; isdigit(s[i]); i++) val = 10.0 * val + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = 10.0 * val + (s[i] - '0'); power *= 10; } return sign * val / power;}

#include <ctype.h>

/* atof: convert string s to double */double atof(char s[]){ double val, power; int i, sign;

for (i = 0; isspace(s[i]); i++) ; /* skip white space */ sign = (s[i] == '-') ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; for (val = 0.0; isdigit(s[i]); i++) val = 10.0 * val + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = 10.0 * val + (s[i] - '0'); power *= 10; } return sign * val / power;}

int atoi(char s[])

{

return atof(s);

}

int atoi(char s[])

{

return atof(s);

}

Example:Caculator#include <stdio.h>

#define MAXLINE 100

/* rudimentary calculator */

main()

{

double sum, atof(char []);

char line[MAXLINE];

int getline(char line[], int max);

sum = 0;

while (getline(line, MAXLINE) > 0)

printf("\t%lf\n", sum += atof(line));

return 0;

}

#include <stdio.h>

#define MAXLINE 100

/* rudimentary calculator */

main()

{

double sum, atof(char []);

char line[MAXLINE];

int getline(char line[], int max);

sum = 0;

while (getline(line, MAXLINE) > 0)

printf("\t%lf\n", sum += atof(line));

return 0;

}

Exercises

2. Extend atof to handle scientific notation of the form 123.45e-6

3. Write a program to solve equation ax2 + bx + c =0.The programs must be handle all possible cases.

Programming Language CFunctions and Program Structure

External

Variables

How Functions Get Communicated?

By passing parameters among functions– C uses call-by-value mechanism

By returning value to the caller

By using shared variables– In C, it is called external variables

– Side effects by functions

External/Global Variables

External variables are defined outside any function and blocks

Functions themselves are always external– not allowed to be nestedly defined.

External variables can be affected by all functions (unlike parameters or automatic variables)– E.g., stacks, queue, list, database, …..

Example: Reverse Polish Calculator

Infix notation:

(1 - 2) * (4 + 5)

Reverse Polish notation:

1 2 - 4 5 + *

Reverse Polish Calculator

1 2 - 4 5 + *

1

Reverse Polish Calculator

1 2 - 4 5 + *

12

Reverse Polish Calculator

1 2 - 4 5 + *

12 1 2- -1

Reverse Polish Calculator

1 2 - 4 5 + *

-11 2- -1

Reverse Polish Calculator

1 2 - 4 5 + *

-14

Reverse Polish Calculator

1 2 - 4 5 + *

-145

Reverse Polish Calculator

1 2 - 4 5 + *

-145

4 5+ 9

Reverse Polish Calculator

1 2 - 4 5 + *

-19 4 5+ 9

Reverse Polish Calculator

1 2 - 4 5 + *

-19 -1 9* -9

Reverse Polish Calculator

1 2 - 4 5 + *

-9-1 9* -9

Reverse Polish Calculator

1 2 - 4 5 + *

-9 -9

Reverse Polish Calculator

1 2 - 4 5 + *

Shared byStack

push()

pop()

Pseudo Code Reverse Polish Calculator

while (next operator or operand is not end-of-file indicator)

if (number)

push it

else if (operator)

pop operands

do operation

push result

else if (newline)

pop and print top of stack

else

error

while (next operator or operand is not end-of-file indicator)

if (number)

push it

else if (operator)

pop operands

do operation

push result

else if (newline)

pop and print top of stack

else

error

#include <stdio.h>#include <stdlib.h> /* for atof() */

#define MAXOP 100 /* max size of operand or operator */#define NUMBER '0' /* signal that a number was found */

int getop(char []);void push(double);double pop(void);

/* reverse Polish calculator */main(){ int type; double op2; char s[MAXOP];

while ((type = getop(s)) != EOF) { switch (type) { case NUMBER: push(atof(s)); break; case '+': push(pop() + pop()); break; case '*': push(pop() * pop()); break; case '-': op2 = pop(); push(pop() - op2); break; case '/': op2 = pop(); if (op2 != 0.0) push(pop() / op2); else printf("error: zero divisor\n"); break; case '\n': printf("\t%.8lf\n", pop()); break; default: printf("error: unknown command %s\n", s); break; } } return 0;}

#include <stdio.h>#include <stdlib.h> /* for atof() */

#define MAXOP 100 /* max size of operand or operator */#define NUMBER '0' /* signal that a number was found */

int getop(char []);void push(double);double pop(void);

/* reverse Polish calculator */main(){ int type; double op2; char s[MAXOP];

while ((type = getop(s)) != EOF) { switch (type) { case NUMBER: push(atof(s)); break; case '+': push(pop() + pop()); break; case '*': push(pop() * pop()); break; case '-': op2 = pop(); push(pop() - op2); break; case '/': op2 = pop(); if (op2 != 0.0) push(pop() / op2); else printf("error: zero divisor\n"); break; case '\n': printf("\t%.8lf\n", pop()); break; default: printf("error: unknown command %s\n", s); break; } } return 0;}

#define MAXVAL 100 /* maximum depth of val stack */

int sp = 0; /* next free stack position */

double val[MAXVAL]; /* value stack */

/* push: push f onto value stack */

void push(double f)

{

if (sp < MAXVAL)

val[sp++] = f;

else

printf("error: stack full, can't push %g\n", f);

}

/* pop: pop and return top value from stack */

double pop(void)

{

if (sp > 0)

return val[--sp];

else {

printf("error: stack empty\n");

return 0.0;

}

}

#define MAXVAL 100 /* maximum depth of val stack */

int sp = 0; /* next free stack position */

double val[MAXVAL]; /* value stack */

/* push: push f onto value stack */

void push(double f)

{

if (sp < MAXVAL)

val[sp++] = f;

else

printf("error: stack full, can't push %g\n", f);

}

/* pop: pop and return top value from stack */

double pop(void)

{

if (sp > 0)

return val[--sp];

else {

printf("error: stack empty\n");

return 0.0;

}

}

#include <ctype.h>

int getch(void);

void ungetch(int);

/* getop: get next character or numeric operand */

int getop(char s[])

{

int i, c;

while ((s[0] = c = getch()) == ' ' || c == '\t') ;

s[1] = '\0';

if (!isdigit(c) && c != '.') return c; /* not a number */

i = 0;

if (isdigit(c)) /* collect integer part */

while (isdigit(s[++i] = c = getch())) ;

if (c == '.') /* collect fraction part */

while (isdigit(s[++i] = c = getch())) ;

s[i] = '\0';

if (c != EOF) ungetch(c);

return NUMBER; /* a number */

}

#include <ctype.h>

int getch(void);

void ungetch(int);

/* getop: get next character or numeric operand */

int getop(char s[])

{

int i, c;

while ((s[0] = c = getch()) == ' ' || c == '\t') ;

s[1] = '\0';

if (!isdigit(c) && c != '.') return c; /* not a number */

i = 0;

if (isdigit(c)) /* collect integer part */

while (isdigit(s[++i] = c = getch())) ;

if (c == '.') /* collect fraction part */

while (isdigit(s[++i] = c = getch())) ;

s[i] = '\0';

if (c != EOF) ungetch(c);

return NUMBER; /* a number */

}

#define BUFSIZE 100

char buf[BUFSIZE]; /* buffer for ungetch */

int bufp = 0; /* next free position in buf */

int getch(void) /* get a (possibly pushed-back) character */

{

return (bufp > 0) ? buf[--bufp] : getchar();

}

void ungetch(int c) /* push character back on input */

{

if (bufp >= BUFSIZE)

printf("ungetch: too many characters\n");

else

buf[bufp++] = c;

}

#define BUFSIZE 100

char buf[BUFSIZE]; /* buffer for ungetch */

int bufp = 0; /* next free position in buf */

int getch(void) /* get a (possibly pushed-back) character */

{

return (bufp > 0) ? buf[--bufp] : getchar();

}

void ungetch(int c) /* push character back on input */

{

if (bufp >= BUFSIZE)

printf("ungetch: too many characters\n");

else

buf[bufp++] = c;

}

Exercises

4. Add access to library functions like sin, exp, and pow. Use <math.h>.

5. Add commands for handling variables. (It's easy to provide twenty-six variables with single-letter names.).

Programming Language CFunctions and Program Structure

Header Files

Scope Rules The scope of a variable is the part of the prog

ram within which the name can be used.

Basic rule:Identifier (or variables) are accessible only within the block in which they are declared or defined.

Definition vs. Declaration

Declarations– announce the properties (primarily types) of objects

(variables or functions)– make the compiler knowing how to create code to use

objects– e.g., declaration of external variables and function

prototypes– there may be many declarations for one object

Definition– Causes storage to be set aside– One definition for each object

Header Files

Group shared declarations among files in header files– Convenient for development– Make source file shorter– Facilitate maintenance

Reverse Polish Calculator/* calc.h */#define NUMBER '0'void push(double);double pop(void);int getop(char []);int getch(void);void ungetch(int);

/* calc.h */#define NUMBER '0'void push(double);double pop(void);int getop(char []);int getch(void);void ungetch(int);

/* main.c */#include <stdio.h>#include <stdlib.h>#include "calc.h"

#define MAXOP 100main(){ ...............}

/* main.c */#include <stdio.h>#include <stdlib.h>#include "calc.h"

#define MAXOP 100main(){ ...............}

/* getop.c */#include <stdio.h>#include <ctype.h>#include "calc.h"int getop(char s[]){ ...............}

/* getop.c */#include <stdio.h>#include <ctype.h>#include "calc.h"int getop(char s[]){ ...............}

/* stack.c */#include <stdio.h>#include "calc.h"

#define MAXVAL 100 int sp = 0;double val[MAXVAL];void push(double f){ ...............}

double pop(void){ ...............}

/* stack.c */#include <stdio.h>#include "calc.h"

#define MAXVAL 100 int sp = 0;double val[MAXVAL];void push(double f){ ...............}

double pop(void){ ...............}

/* getch.c */#include <stdio.h>#include "calc.h"

#define BUFSIZE 100char buf[BUFSIZE];int bufp = 0;int getch(void){ ...............}

void ungetch(int c){ ...............}

/* getch.c */#include <stdio.h>#include "calc.h"

#define BUFSIZE 100char buf[BUFSIZE];int bufp = 0;int getch(void){ ...............}

void ungetch(int c){ ...............}

Programming Language CFunctions and Program Structure

Static

Variables

Reverse Polish Calculator/* calc.h */#define NUMBER '0'void push(double);double pop(void);int getop(char []);int getch(void);void ungetch(int);

/* calc.h */#define NUMBER '0'void push(double);double pop(void);int getop(char []);int getch(void);void ungetch(int);

/* main.c */#include <stdio.h>#include <stdlib.h>#include "calc.h"

#define MAXOP 100main(){ ...............}

/* main.c */#include <stdio.h>#include <stdlib.h>#include "calc.h"

#define MAXOP 100main(){ ...............}

/* getop.c */#include <stdio.h>#include <ctype.h>#include "calc.h"int getop(char s[]){ ...............}

/* getop.c */#include <stdio.h>#include <ctype.h>#include "calc.h"int getop(char s[]){ ...............}

/* stack.c */#include <stdio.h>#include "calc.h"

#define MAXVAL 100 int sp = 0;double val[MAXVAL];void push(double f){ ...............}

double pop(void){ ...............}

/* stack.c */#include <stdio.h>#include "calc.h"

#define MAXVAL 100 int sp = 0;double val[MAXVAL];void push(double f){ ...............}

double pop(void){ ...............}

/* getch.c */#include <stdio.h>#include "calc.h"

#define BUFSIZE 100char buf[BUFSIZE];int bufp = 0;int getch(void){ ...............}

void ungetch(int c){ ...............}

/* getch.c */#include <stdio.h>#include "calc.h"

#define BUFSIZE 100char buf[BUFSIZE];int bufp = 0;int getch(void){ ...............}

void ungetch(int c){ ...............}

Don’t be referenced by

other files

Don’t be referenced by

other files

External Static Variables/* calc.h */#define NUMBER '0'void push(double);double pop(void);int getop(char []);int getch(void);void ungetch(int);

/* calc.h */#define NUMBER '0'void push(double);double pop(void);int getop(char []);int getch(void);void ungetch(int);

/* main.c */#include <stdio.h>#include <stdlib.h>#include "calc.h"

#define MAXOP 100main(){ ...............}

/* main.c */#include <stdio.h>#include <stdlib.h>#include "calc.h"

#define MAXOP 100main(){ ...............}

/* getop.c */#include <stdio.h>#include <ctype.h>#include "calc.h"int getop(char s[]){ ...............}

/* getop.c */#include <stdio.h>#include <ctype.h>#include "calc.h"int getop(char s[]){ ...............}

/* stack.c */#include <stdio.h>#include "calc.h"

#define MAXVAL 100 int sp = 0;double val[MAXVAL];void push(double f){ ...............}

double pop(void){ ...............}

/* stack.c */#include <stdio.h>#include "calc.h"

#define MAXVAL 100 int sp = 0;double val[MAXVAL];void push(double f){ ...............}

double pop(void){ ...............}

/* getch.c */#include <stdio.h>#include "calc.h"

#define BUFSIZE 100char buf[BUFSIZE];int bufp = 0;int getch(void){ ...............}

void ungetch(int c){ ...............}

/* getch.c */#include <stdio.h>#include "calc.h"

#define BUFSIZE 100char buf[BUFSIZE];int bufp = 0;int getch(void){ ...............}

void ungetch(int c){ ...............}

/* stack.c */#include <stdio.h>#include "calc.h"

#define MAXVAL 100 static int sp = 0;static double val[MAXVAL];void push(double f){ ...............}

double pop(void){ ...............}

/* stack.c */#include <stdio.h>#include "calc.h"

#define MAXVAL 100 static int sp = 0;static double val[MAXVAL];void push(double f){ ...............}

double pop(void){ ...............}

/* getch.c */#include <stdio.h>#include "calc.h"

#define BUFSIZE 100static char buf[BUFSIZE];Static int bufp = 0;int getch(void){ ...............}

void ungetch(int c){ ...............}

/* getch.c */#include <stdio.h>#include "calc.h"

#define BUFSIZE 100static char buf[BUFSIZE];Static int bufp = 0;int getch(void){ ...............}

void ungetch(int c){ ...............}

The static declaration for an external variable or function, limits the scope of that object to the rest of the source file being compiled.

Internal Static Variables

Internal static variables are local to a particular function just as automatic variables.

Unlike automatics, they remain in existence rather than coming and going each time the function is activated.

Programming Language CFunctions and Program Structure

Recursion

Recursion C functions may be used recursively; i.e., a function

may call itself either directly or indirectly.#include <stdio.h>

/* printd: print n in decimal */

void printd(int n)

{

if (n < 0) {

putchar('-');

n = -n;

}

if (n / 10) printd(n / 10);

putchar(n % 10 + '0');

}

#include <stdio.h>

/* printd: print n in decimal */

void printd(int n)

{

if (n < 0) {

putchar('-');

n = -n;

}

if (n / 10) printd(n / 10);

putchar(n % 10 + '0');

}

Example: qsort

qsort

qsort qsort

Example: qsort/* qsort: sort v[left]...v[right] into increasing order */

void qsort(int v[], int left, int right)

{

int i, last;

if (left >= right) /* do nothing if array contains */

return; /* fewer than two elements */

swap(v, left, (left + right)/2); /* move partition elem */

last = left; /* to v[0] */

for (i = left + 1; i <= right; i++) /* partition */

if (v[i] < v[left]) swap(v, ++last, i);

swap(v, left, last); /* restore partition elem */

qsort(v, left, last-1);

qsort(v, last+1, right);

}

/* qsort: sort v[left]...v[right] into increasing order */

void qsort(int v[], int left, int right)

{

int i, last;

if (left >= right) /* do nothing if array contains */

return; /* fewer than two elements */

swap(v, left, (left + right)/2); /* move partition elem */

last = left; /* to v[0] */

for (i = left + 1; i <= right; i++) /* partition */

if (v[i] < v[left]) swap(v, ++last, i);

swap(v, left, last); /* restore partition elem */

qsort(v, left, last-1);

qsort(v, last+1, right);

}

Example: qsort

/* swap: interchange v[i] and v[j] */

void swap(int v[], int i, int j)

{

int temp;

temp = v[i];

v[i] = v[j];

v[j] = temp;

}

/* swap: interchange v[i] and v[j] */

void swap(int v[], int i, int j)

{

int temp;

temp = v[i];

v[i] = v[j];

v[j] = temp;

}

Example: qsort

int vals[]={12, 9, 35, 25, 7, 40, 11};

void qsort(int v[], int left, int right);

main()

{

qsort(vals, 0, 6);

}

int vals[]={12, 9, 35, 25, 7, 40, 11};

void qsort(int v[], int left, int right);

main()

{

qsort(vals, 0, 6);

}

Example: qsort

int vals[]={12, 9, 35, 25, 7, 40, 11};

void qsort(int v[], int left, int right);

main()

{

qsort(vals, 0, 6);

}

int vals[]={12, 9, 35, 25, 7, 40, 11};

void qsort(int v[], int left, int right);

main()

{

qsort(vals, 0, 6);

}

Exercises

6. Adapt the ideas of printd to write a recursive version of itoa; that is, convert an integer into a string by calling a recursive routine.

7. Write a recursive version of the function reverse(s), which reverses the string s in place.

Recommended