Вы находитесь на странице: 1из 6

C Functions

 C function is used to define


CS1010E Lecture 7 – value-returning function
C Functions as Procedures – procedure
 In general, a C function allows
Henry Chia (hchia@comp.nus.edu.sg) – multiple arguments or no arguments
– one return value or none at all
Semester 1 2017 / 2018
# of arguments
0 1 or more
0 rarely used procedures
# of return values
1 rarely used value-returning functions

1 / 24 3 / 24

Lecture Outline Function Definition

 Defining procedures function-definition

 Function call statement / return statement


void func-id ( void ) func-body
 Procedures for
type parameter-decl
– Program output
– Multiple function output ,

 Functional abstraction parameter-decl

– Structured programming and top-down design type var-id


– Modular-design principles
 type: type of return value; void if no return value
 func-id: meaningful function or parameter name
 parameter: parameter declaration; void for no parameters

2 / 24 4 / 24
Function Call and Return Statements Procedure: Multiple Function Output

function-statement  A function can only return at most one value


 Example: Given a time duration (in seconds), compute the
func-id ( ) ; equivalent number of hours, minutes and seconds
expr  Solution #1: do-it-yourself!
#include <stdio.h>
, int main(void) {
int t, h, m, s;
return-statement
printf("Enter duration (secs): ");
scanf("%d", &t);
return ;
h = t / 3600;
m = (t % 3600) / 60;
expr s = t % 60;
printf("Duration: %d:%d:%d\n", h, m, s);
return 0;
}

5 / 24 7 / 24

Procedure: Program Output Procedure: Multiple Function Output

 Useful for complex printing tasks  Solution #2: Get a procedure to do it. Does this work?
#include <stdio.h>
#include <stdio.h> void splitTime(int t, int h, int m, int s);
void printRowOfStars(int n); void printRowOfStars(int n) { int main(void) {
void printPattern(int n); if (n == 0) { int t, h, m, s;
printf("\n");
int main(void) { } else { printf("Enter duration (secs): ");
int n; printf("*"); scanf("%d", &t);
scanf("%d", &n); printRowOfStars(n - 1); splitTime(t, h, m, s);
printPattern(n); } printf("Duration: %d:%d:%d\n", h, m, s);
return; return 0;
return 0; } }
} /*
void printPattern(int n) { void splitTime(int t, int h, int m, int s) {
if (n > 0) { h = t / 3600;
printRowOfStars(n); m = (t % 3600) / 60;
printPattern(n - 1); s = t % 60;
} return;
return; }

6 / 24 8 / 24
Pass-by-Value Revisited Variable Access Across Functions

 Recall pass-by-value  To enable function output via the parameters, use pointers
to store address values (e.g. scanf)
main splitTime
int main(void) {
9999 t 9999 t int t, h, m, s;
?a h
*
?a h printf("Enter duration (secs): ");
?b m
9999,?a,?b,?c
?b m
scanf("%d", &t);

?c s ?c s
splitTime(t, &h, &m, &s);

splitTime(t,h,m,s);
printf("Duration: %d:%d:%d\n", h, m, s);
return 0;
}
 How to define parameters of the splitTime function?

9 / 24 11 / 24

Pass-by-Value Revisited Function Output Parameter

 Just before splitTime function returns


function-definition

main splitTime
void func-id ( void ) func-body
9999 t 9999 t

?a h 2 h type parameter-decl
*
9999,?a,?b,?c
?b m 46 m ,

?c s 39 s
parameter-decl
splitTime(t,h,m,s);
input-parameter-decl
type var-id

output-parameter-decl
 What happens to the variables in the main function? type * var-id

10 / 24 12 / 24
Function Output Parameter Function Output Parameter

 Declared as a pointer in the function header  Just before splitTime function returns
 Accessed via dereferencing in the function body
main splitTime
/* t 9999 9999 t
Function splitTime takes t in seconds, splits and
h 2 h
outputs the hours, minutes and seconds through the

output parameters h, m and s. m 46  m
Precondition: t >= 0 s 39  s
*/
void splitTime(int t, int *h, int *m, int *s) { splitTime(t,&h,&m,&s); -
*h = t / 3600; 9999,&h,&m,&s
*m = (t % 3600) / 60;
*s = t % 60;  Values are “returned” through the function output
return; parameters; does not violate lexical scoping
}

13 / 24 15 / 24

Function Output Parameter Example: Swapping Variable Contents

 Calling splitTime with function output parameters  Using main function to swap the contents of two variables

main splitTime #include <stdio.h>


t 9999 9999 t
int main(void) {
h ?a  h
int x, y, temp;

m ?b  m printf("Enter x and y: ");


scanf("%d%d", &x, &y);
s ?c  s
temp = x;
splitTime(t,&h,&m,&s); - x = y;
9999,&h,&m,&s y = temp;
printf("x=%d; y=%d\n", x, y);
 Passing &h, &m and &s to splitTime gives it access to
variables h, m and s in main return 0;
}

14 / 24 16 / 24
Example: Swapping Variable Contents Example: Calculate Taxi Fare (Revisited)

 Using a swap function  Calculate the taxi fare based on the following fare structure:

#include <stdio.h> Meter Fare Normal Limousine Chrysler


void swap(int *x, int *y) {
int temp; Flag-Down (inclusive of 1st km or less) $3.40 $3.90 $5.00
void swap(int *x, int *y); Every 400m thereafter or less up to 10km $0.22 $0.22 $0.33
temp = *x; Every 350 metres thereafter or less after 10 km $0.22 $0.22 $0.33
int main(void) { *x = *y;
int x, y; *y = temp;
 Input:
printf("Enter x and y: "); return;
scanf("%d%d", &x, &y); } – Type of taxi: Normal(1), Limousine(2), Chrysler(3)
– Distance travelled: non-negative integer
swap(&x, &y);
printf("x=%d; y=%d\n", x, y);
 Sample Run:
1 12500
return 0;
} $10.20
 Peak-hour surcharge is ignored; you can extend that later
17 / 24 19 / 24

Designing Solutions for “Large” Problems Top-level program


#include <stdio.h>
 Break down large problem into smaller/simpler sub-problems int computeFare(int type, int dist);
void printFare(int fare);
 Define functions/procedures to handle each sub-problem
int main(void) {
 Functional abstraction int type, dist, fare;

– Know what a function does, not how it is done scanf("%d%d", &type, &dist);
fare = computeFare(type, dist);
printFare(fare);
 Structured programming return 0;
}
– Programs having a logical structure that makes them
int computeFare(int type, int dist) {
easy to read, understand and modify return 1022;
}
– Adopt a top-down modular design methodology:
void printFare(int fare) {
⊲ Start with the “large” task and break into sub-tasks printf("$%d.%d0\n", fare / 100, (fare % 100) / 10);
return;
⊲ Break these sub-tasks into smaller sub-tasks until the }
smallest ones have trivial solutions  Since computeFare might require further decomposition,
⊲ Compose all sub-tasks to solve the original problem replace with a “stub”, so that program can still be tested
18 / 24 20 / 24
Breaking down computeFare Principles in Modular Design
int computeFare(int type, int dist) {
int fare;  Abstraction
if (dist == 0) {
fare = 0; – Know what it does but don’t care how it is done
} else if (dist <= 1000) {
fare = stage1Fare(type);  Reusability
} else if (dist <= 10000) {
fare = stage1Fare(type) + stage2Fare(type, dist-1000); – Identify modules that can be used repeatedly
} else {
fare = stage1Fare(type) + stage2Fare(type, 9000) + – One function definition; many calls to the same function
stage3Fare(type, dist-10000);
}  High cohesion
return fare;
} – Do only one thing, and do it well
 Breakdown computeFare into fare stages via stubs  Loose coupling
int stage1Fare(int type) { int stage2Fare(int type, int stage3Fare(int type,
– Minimize the use of “output parameters” that allows one
printf("stage1\n");
return 0;
int dist) {
printf("stage2\n");
int dist) {
printf("stage3\n"); module to directly change properties (variables) of
} return 0; return 0;
} } another module
21 / 24 23 / 24

Calculating Fares for Different Stages Lecture Summary


int stage1Fare(int type) { int stage2Fare(int type, int dist) {
if (type == NORMAL) int rate;
return 340; rate = getRate(type);  Application of user-defined functions as value-returning
else if (type == LIMOUSINE) return computeStage(dist, rate, 400);
return 390; } functions or procedures
else if (type == CHRYSLER)
return 500; int stage3Fare(int type, int dist) {  Use of function output parameters to simulate “multiple
else int rate;
return 0; rate = getRate(type); return values”
} return computeStage(dist, rate, 350);  Are value-returning functions that return a single value no
}
int getRate(int type) { longer necessary? What about function composition?
if (type == NORMAL) sqrt((b * b) + (c * c) - (2 * b * c * cos(alpha * PI / 180)));
return 22;
else if (type == LIMOUSINE)
return 22;  Functional abstraction and top-down design
else if (type == CHRYSLER)
return 33; – Identify that a large problem can be broken down into
else
return 0; smaller and simpler sub-problems
}
– Apply modular design principles to develop each module
int computeStage(int dist, int rate, int block) {
return ( ( (dist - 1) / block ) + 1 ) * rate; incrementally
}
22 / 24 24 / 24

Вам также может понравиться