Writing functions with arguments and results, 3 examples: double circ_area(double r) { double pi = 3.14159; return pi * r * r; } double rect_area(double l, double w) { return l * w; } double tri_area(double b, double h) { return 0.5 * b * h; } Each function returns a type double result. The result returned is the value of the expression after the word return Notice that these functions do not read any values (no scanf calls). Nor do they display their results (no printf calls) – they return results – the main function can display them if it needs to. Each function has 1 or 2 formal parameters (r, l, w, b, h). These formal parameters represent the actual data that the function will process. They are function inputs – their values are determined when we call the function. Again, notice that the function does not read these values! Assume radius, diameter, len, and wid are declared and set in function main. Sample calls: area = circ_area(5.0); /* r is 5.0 */ area = circ_area(radius); /* r has value of radius */ area = circ_area(diameter / 2); /* r has the value of the expression diameter/2 */ area = rect_area(10.0, 5.0); /* l is 10, w is 5 */ area = rect_area(5.0, 10.0); /* l is 5, w is 10 */ area = rect_area(len, wid); /* l is len, w is wid */ Let’s use rect_area in the mowing problem: #include double rect_area(double, double); int main() { double house_l, house_w, yard_l, yard_w, house_a, yard_a, grass_a; /* Read house & yard dimensions*/ printf(“Enter house width & length:”); scanf(“%lf%lf”, &house_l, &house_w); printf(“Enter yard width & length:”); scanf(“%lf%lf”, &yard_l, &yard_w); /*Calculate grass area using rect_area*/ yard_a = rect_area(yard_l, yard_w); house_a =rect_area(house_l, house_w); grass_a = yard_a – house_a; ... return 0; } /* end of main */ double rect_area(double l, double w) { return l * w; } /* end of rect_area */ A more interesting function: /* finds the area of a triangle, * circle, or rectangle. First argument * (type char) specifies type of figure. * Next arguments specify dimensions. */ double find_area(char fig, double d1, double d2) { double area; if (fig == ‘R’ || fig == ‘r’) area = rect_area(d1, d2); else if (fig == ‘T’ || fig == ‘t’) area = tri_area(d1, d2); else if (fig == ‘C’ || fig == ‘c’) area = circ_area(d1); else { printf(”Unknown figure type %c\n”, fig); area = 0; } return area; } To use this function: you call it in the following way. int main() { double side1, side2; /*inputs*/ double a1, a2, a3; /* outputs */ /* read in data values for all input * variables using printf, scanf */ ... /* sample calls */ a1 = find_area(‘R’, side1, side2); a2 = find_area(‘T’, side2, side1); a3 = find_area(‘c’, 5.0, 5.0); /* bad calls */ a1 = find_area(side1, side2, ‘R’); a2 = find_area(“C”, 6.5, 9.2); a3 = find_area(‘R’, w, l); Function main data area at time of first call a1 = find_area(‘R’, side1, side2); a1 a2 a3 side1 side2 ? ? ? 100 80 Function find_area data area after call: fig d1 d2 area ‘R’ 100 80 ? Function rect_area data area after its call: l d 100 80 Function find_area data area after return from function rect_area fig d1 d2 area ‘R’ 100 80 8000 Function main data area after return from find_area: a1 a2 a3 side1 side2 8000 ? ? 100 80 Scope of identifiers – determines where you can reference an identifier. For identifiers declared before main function – scope is global – they can be referenced anywhere. Normally, constants (using define) and function names are declared global. For all other identifiers, their scope is the function in which they are declared. 4 identifiers are declared below. Three are formal parameters (fig, d1, d2) and one is a “local variable”. These identifiers can only be referenced inside function find_area – not in main or rect_area. double find_area(char fig, double d1, double d2) { double area; Similarly, identifiers declared in main (side1, side2, a1, a2, a3) and identifiers declared in rect_area (l, d) can be referenced only in the functions that declare them – not in find_area. Sometimes there will be two declarations of the same identifier: int main() { int quarters, dimes, … … } int calc_coins_value(int quarters, int dimes, … ) { We use the same names in both functions because it makes sense to do so. However, there are really 2 identifiers named quarters (a variable in main, and a formal parameter in calc_coins_value) and the compiler keeps them separate. In main, the function call: calc_coins_value(quarters, dimes, …); causes the value of input variable quarters (or dimes) in main to be passed to formal parameter quarters (or dimes) in calc_coins_value. Review of 3 things you must do to use functions: 1. Provide a prototype before function main. This gives C the information it needs to translate a call to the function. Prototype gives the function result (void or something else), function name, and data types of its formal parameters. Ends with a semicolon. void instruct(); double find_area(char, double, double); 2. Wherever you want the function body to execute, insert a function call. Function call specifies the function name and the actual arguments the function should process. C evaluates the arguments and transfers to the code for the function body. instruct(); area = find_area(‘R’, 50.0, 75.0); Note: variable area in above assignment statement is separate from variable area in function find_area. 3. Provide the function definition after function main. It must be consistent with prototype and vice-versa. void instruct() { /* body of instruct goes here. */ } double find_area(char fig, double d1, double d2) { /* body of find_area goes here. */ }