440 likes | 590 Views
CS1010: Programming Methodology http://www.comp.nus.edu.sg/~cs1010/. Week 6: Modular Programming – More about Functions. Objectives: Understand how to use pointers to return more than one value in a function
E N D
CS1010: Programming Methodologyhttp://www.comp.nus.edu.sg/~cs1010/
Week 6: Modular Programming – More about Functions • Objectives: • Understand how to use pointers to return more than one value in a function • Understand how to use header files and separate compilation to make your program modular • References: • Chapter 5: Functions • Chapter 8, Lesson 8.8 CS1010 (AY2013/4 Semester 1)
Outline (1/2) • Week 5 Exercise 4: Prime Number • Functions Revisit • Pointer Variables 3.1 Demo #1 3.2 Common Mistake • Functions with ¶meters • Exercise #1: Code tracing • Warning! Global Variables • Modularization and Interfaces • Separate Compilation CS1010 (AY2013/4 Semester 1)
Outline (2/2) • Quizzes • Exercise #2: Volume and Surface Area of Cuboid • Exercise #3: Triangle Centroid (take-home) CS1010 (AY2013/4 Semester 1)
1. Week 5 Exercise #4: Prime Number • Primality test is a classic programming problem • Given a positive integer, determine whether it is a prime. • A prime number has two distinct factors (divisors): 1 and itself. Examples: 2, 3, 5, 7, 11, ... (Note: 1 is not a prime!) • Write a program Week5_PrimeTest.c. You should include a functionis_prime(int). (What does it return?) • Sample runs: Enter a positive integer: 131 131 is a prime. Enter a positive integer: 713 713 is not a prime. CS1010 (AY2013/4 Semester 1)
2. Functions: Revisit (1/3) • In week 3, we learned about functions • In C, a function maps some input values to zero or more output values • Zero output through “voidfunc ( … ) { … };” • One output through, e.g., “doublefunc ( … ) { …; returnvalue; };” • More outputs through changing input values • ‘&’– ‘address of’ operator • ‘*’– ‘indirection’ operator; go to the address stored in the variable following the * to get the value at that address or put a value there. • We have done void functions and functions that return a single value, how about functions that return more than one value? CS1010 (AY2013/4 Semester 1)
2. Functions: Revisit (2/3) • But a function can return only one value! • What is the output of this program? Week6_MultipleReturns.c #include <stdio.h> int f(int, int, int); int main(void) { int a = 9, b = -2, c = 5; printf("Result = %d\n", f(a,b,c)); return0; } int f(int x, int y, int z) { returnx+y; returny+z; returnz+x; } CS1010 (AY2013/4 Semester 1)
2. Functions: Revisit (3/3) • What if we really need to “return” more than one value to the caller? • 2 possible approaches • Approach 1 • Returning a collection of data (e.g.: array, structure) • We will discuss this another time • Approach 2 • Declare variables in the caller to hold these values, and pass the addresses of these variables to the function • This involves the use of & (address operator) and * (indirection operator; also known as the dreaded pointer); it does not use the return keyword CS1010 (AY2013/4 Semester 1)
3. Pointer Variables (1/2) • A pointer variable (or simply, pointer) stores the address of another variable • Hence, we must indicate (1) that it is a pointer, and (2) the type of the other variable it “points” to • C provides two unary pointer operators • Address operator & • Indirection operator * • Example: i j p 10 20 inti = 10, j = 20; int*p; // p is a pointer to some intvariable p = &i; // p now stores the address of variable i printf("value of i is %d\n", *p); value of i is 10 Important! Now *p is equivalent to i CS1010 (AY2013/4 Semester 1)
3. Pointer Variables (2/2) 12 12 inti = 10, j = 20; int *p; // p is a pointer to some int variable p = &i; // p now stores the address of variable i printf("value of i is%d\n", *p); • Example (cont.): i j p 10 20 // *p accesses the value of pointed/referred variable *p = *p + 2; // increment *p (which is i) by 2 // same effect as: i = i + 2; p = &j; // p now stores the address of variable j *p = i; // value of *p (which is j now) becomes 12 // same effect as: j = i; CS1010 (AY2013/4 Semester 1)
3.1 Pointer Variables: Demo #1 (1/2) Week6_Pointers.c #include <stdio.h> int main(void) { double a, *b; b = &a; *b = 12.34; printf("%f\n", a); return0; } Can you draw the picture? What is the output? What is the output if the printf() statement is changed to the following? printf("%f\n", *b); printf("%f\n", b); printf("%f\n", *a); CS1010 (AY2013/4 Semester 1)
3.1 Pointer Variables: Demo #1 (2/2) • How do we interpret the declaration? • double a, *b; • The above is equivalent to • double a; // this is straight-forward: a is a double variable • double *b; • We can read the second declaration as • *b is a double variable, so this implies that ... • b is a pointer to some double variable • The following are equivalent: double a; double *b; b = &a; double a; double *b = &a; double a; double b = &a; But this is not the same as above (and it is not legal): CS1010 (AY2013/4 Semester 1)
3.2 Pointer Variables: Common Mistake Week6_Pointers_Common_Mistake.c #include <stdio.h> int main(void) { int *n; *n = 123; printf("%d\n", *n); return0; } What’s wrong with this? Can you draw the picture? • Where is the pointer n pointing to? • Where is the value 123 assigned to? • Result: CS1010 (AY2013/4 Semester 1)
4. Functions with ¶meters (1/6) Week6_FunctionDemo1.c #include <stdio.h> void f(int, int,int); int main(void) { int a = 9, b = -2, c = 5; f(a, b, c); printf("a = %d, b = %d, c = %d\n", a, b, c); return 0; } void f(int x, int y, int z) { x = 3 + y; y = 10 * x; z = x + y + z; printf("x = %d, y = %d, z = %d\n", x, y, z); } a b c 9 -2 5 CS1010 (AY2013/4 Semester 1)
4. Functions with ¶meters (2/6) Week6_FunctionDemo2.c #include <stdio.h> voidf(int *, int *, int *); int main(void) { int a = 9, b = -2, c = 5; f(&a, &b, &c); printf("a = %d, b = %d, c = %d\n", a, b, c); return 0; } void f(int *x, int *y, int *z) { *x = 3 + *y; *y = 10 * *x; *z = *x + *y + *z; printf("*x = %d, *y = %d, *z = %d\n", *x, *y, *z); } a b c 9 -2 5 CS1010 (AY2013/4 Semester 1)
4. Functions with ¶meters (3/6) Week6_FunctionDemo3.c #include<stdio.h> void f(int *, int *, int *); int main(void) { int a = 9, b = -2, c = 5; f(&a, &b, &c); printf("a = %d, b = %d, c = %d\n", a, b, c); return0; } void f(int *x, int *y, int *z) { *x = 3 + *y; *y = 10 * *x; *z = *x + *y + *z; printf("x = %d, y = %d, z = %d\n", x, y, z); } CS1010 (AY2013/4 Semester 1)
4. Functions with ¶meters (4/6) Week6_FunctionDemo4.c #include<stdio.h> void f(int *, int *, int *); int main(void) { int a = 9, b = -2, c = 5; f(&a, &b, &c); printf("a = %d, b = %d, c = %d\n", a, b, c); return 0; } void f(int*x, int *y, int *z) { *x = 3 + *y; *y = 10 * *x; *z = *x + *y + *z; printf("x = %p, y = %p, z = %p\n", x, y, z); } Use %p for pointers. CS1010 (AY2013/4 Semester 1)
4. Functions with ¶meters (5/6) #include <stdio.h> void swap(int, int); int main(void) { int a = 9, b = -2; swap(a, b); printf("a = %d, b = %d\n", a, b); return0; } void swap(int x, int y) { int temp; temp = x; x = y; y = temp; } • One useful application: swapping of 2 variables Does this work? Why or why not? CS1010 (AY2013/4 Semester 1)
4. Functions with ¶meters (6/6) • Can you correct the previous program? (Answer will be shown in class.) CS1010 (AY2013/4 Semester 1)
5. Exercise #1 void f(int w, double x, int *y, double *z) { printf("w = %d, x = %f, y = %p, z = %p\n", w, x, y, z); w = 2 * w; x = 3 * x; *y = *y * 4; *z = 5 * *z; } • Trace the code manually. What are the outputs? #include <stdio.h> void f(int, double, int *, double *); int main(void) { inta = 5; double b = 7.1; intc = 12; double d = 22.3; printf("a = %d, b = %f, c = %d, d = %f\n", a, b, c, d); printf("&a = %p, &b = %p\n", &a, &b); f(c, d, &a, &b); printf("After returning from function f:\n"); printf("a = %d, b = %f, c = %d, d = %f\n", a, b, c, d); return0; } CS1010 (AY2013/4 Semester 1)
6. Warning! Global Variables • We do not encourage the use of global variables. • Variables that are declared outside all functions • Use of global variables will be heavily penalized. #include <stdio.h> #define PI 3.14159 int value; double sum; int main(void) { . . . } This is a constant, not a global variable. These are global variables. CS1010 (AY2013/4 Semester 1)
7. Modularization and Interfaces (1/3) • So far we have compiled our programs directly from the source into an executable: • For the development of large programs with teams of programmers this is not suitable • “break” the program into multiple modules (files) • Compile modules separately • Link all modules into an executable Executable code produces Compiler a.out e.g.: gccwelcome.c CS1010 (AY2013/4 Semester 1)
7. Modularization and Interfaces (2/3) • Header Files and Separate Compilation • Problem is broken into sub-problems and each sub-problem is tackled separately – divide-and-conquer. • Such a process is called modularization. • The modules are possibly implemented by different programmers, hence the need for well-defined interfaces. • The function prototype constitutes theinterface (header file). The function body (implementation) is hidden – abstraction. • Good documentation (example: comment to describe what the method does) aids in understanding. double mean(double, double); // Returns the mean of two double floating-point values. CS1010 (AY2013/4 Semester 1)
7. Modularization and Interfaces (3/3) • Reasons for Modular Programming • Divide problems into manageable parts • Reduce compilation time • Unchanged modules do not need to be re-compiled. • Debug modules separately • Small test programs can be written to exercise the functions in one module. • Build libraries of useful functions • Code can be re-used in different projects. • Faster development. • Do not need to know how some functionality is implemented, e.g., image processing routines. • Example: OpenCV – a computer vision library. CS1010 (AY2013/4 Semester 1)
8. Separate Compilation • In most cases, a module contains functions that are related, e.g., math functions. • A module consists of • A header file (e.g., f1.h). This file contains: • Constant definitions, e.g.: • #define MAX 100 • Function prototypes, e.g.: • double mean(double, double); • A source file (e.g., f1.c). This file contains: • The functions that implement the function prototypes in the header file (e.g., the code for the function mean(…)). • Other functions, variables, and constants that are only used within the module (i.e., they are module-local). f1.h f1.c CS1010 (AY2013/4 Semester 1)
8.1 Separate Compilation, Case 1 Case 1: All the source files are compiled and linked in one step. Sourcefiles.c & .h math.h Libraryfile(s) f1.h libm.a f1.c f2.h -lm f2.c a.out gcc f3.h f3.c Executablefile Compilation and Linking main.c CS1010 (AY2013/4 Semester 1)
8.1 Demo #2: Separate Module • Let’s re-visit our Freezer example. We will create a module that contains a function to calculate the freezer temperature: • Module header file: • Module source file: Week6_FreezerTemp.h // Compute new temperature in freezer floatcalc_temperature(floathours_float); Week6_FreezerTemp.c #include <math.h> // Compute new temperature in freezer floatcalc_temperature(floathours_float) { return ((4.0 * pow(hours_float, 10.0))/(pow(hours_float,9.0) + 2.0)) - 20.0; } CS1010 (AY2013/4 Semester 1)
8.1 Demo #2: Main Module Week6_FreezerMain.c #include <stdio.h> #include "Week6_FreezerTemp.h" intmain(void) { int hours, minutes; floathours_float; // Convert hours and minutes into hours_float float temperature; // Temperature in freezer // Get the hours and minutes printf("Enter hours and minutes since power failure: "); scanf("%d %d", &hours, &minutes); // Convert hours and minutes into hours_float hours_float = hours + minutes/60.0; // Compute new temperature in freezer temperature = calc_temperature(hours_float); // Print new temperature printf("Temperature in freezer = %.2f\n", temperature); return0; } Now we can write aprogram which uses our new external function: CS1010 (AY2013/4 Semester 1)
8.1 Demo #2: Compilation and Linking • Let’s compile and link our program • Case 1: One step compile-and-link • Here the compiler creates temporary object files (which are removed after linking) and directly creates a.out. • Hence you don’t get the chance to see the object files. • (Note: We have omitted the –Wall option above due to space constraint. Please add the option yourself.) $ gcc Week6_FreezerMain.c Week6_FreezerTemp.c -lm CS1010 (AY2013/4 Semester 1)
8.2 Separate Compilation, Case 2 Case 2: Source files are compiled separately and then linked. Sourcefiles.c & .h Objectfiles math.h Libraryfile Compilation f1.h Libm.a f1.c f1.o gcc -c f2.h -lm f2.c f2.o gcc -c a.out gcc f3.h f3.c f3.o Executablefile gcc -c Linking main.c main.o The compiler creates separate object files. gcc -c CS1010 (AY2013/4 Semester 1)
8.2 Demo #3: Compilation and Linking • Let’s compile and link our program • Case 2: 3 steps compile, compile, and link • Here we first create the Week6_FreezerMain.o and Week6_FreezerTemp.o object files. • Then, we link both object files into the a.out executable. • (Note: We have omitted the –Wall option above due to space constraint. Please add the option yourself.) $ gcc –c Week6_FreezerMain.c $ gcc –c Week6_FreezerTemp.c $ gcc Week6_FreezerMain.o Week6_FreezerTemp.o -lm CS1010 (AY2013/4 Semester 1)
8.3 Notes (1/2) • Difference between • #include < … > and #include " … " • Use " … " to include your own header files and < … > to include system header files. The compiler uses different directory paths to find < … > files. • Inclusion of header files • Include *.h files only in *.c files, otherwise duplicate inclusions may happen and later may create problems: • Example: Week6_FreezerTemp.h includes <math.h> Week6_FreezerMain.c includes <math.h> and “Week6_FreezerTemp.h”Therefore, Week6_FreezerMain.c includes <math.h> twice. CS1010 (AY2013/4 Semester 1)
8.3 Notes (2/2) • ‘Undefined symbol’ error • ld: fatal: Symbol referencing errors. • The linker was not able to find a certain function, etc., and could not create a complete executable. • Note: A library can have missing functions it is not a complete executable. • Usually this means you forgot to link with a certain library or object file. This also happens if you mistyped a function name. CS1010 (AY2013/4 Semester 1)
9. Quizzes (1/4) • Complete this Week6_MaxAve_Incomplete.c program that computes the maximum and average of 3 integers in a single function. max_and_average(int, int, int, intmain(void) { int num1, num2, num3; // inputs printf("Enter 3 integers: "); scanf("%d %d %d", &num1, &num2, &num3); printf("Maximum = %d\n", ); printf("Average = %.2f\n", ); return 0; } Week6_MaxAve_Incomplete.c CS1010 (AY2013/4 Semester 1)
9. Quizzes (2/4) • Complete this Week6_MaxAve_Incomplete.c program that computes the maximum and average of 3 integers in a single function. (continued…) max_and_average(int n1, int n2, int n3, { } Week6_MaxAve_Incomplete.c CS1010 (AY2013/4 Semester 1)
9. Quizzes (3/4) • Which of the following is the correct way to read 2 integers through a function? (A) (B) (C) int main(void) { int num1, num2; read_inputs(num1, num2); printf("Values: %d&%d\n", num1, num2); return 0; } void read_inputs(int n1, int n2) { printf("Enter 2 values: "); scanf("%d %d", &n1, &n2); } int main(void) { int num1, num2; read_inputs(&num1, &num2); printf("Values: %d&%d\n", num1, num2); return 0; } void read_inputs(int *n1, int *n2) { printf("Enter 2 values: "); scanf("%d %d", n1, n2); } int main(void) { int num1, num2; read_inputs(&num1, &num2); printf("Values: %d&%d\n", num1, num2); return 0; } void read_inputs(int *n1, int *n2) { printf("Enter 2 values: "); scanf("%d %d", &n1, &n2); } CS1010 (AY2013/4 Semester 1)
9. Quizzes (4/4) • Both are correct, but which is preferred and why? int main(void) { int num1 = 1, num2 = 2; print_values(num1, num2); return 0; } void print_values(int n1, int n2) { printf("Values: %d and %d", n1, n2); } (A) int main(void) { int num1 = 1, num2 = 2; print_values(&num1, &num2); return 0; } void print_values(int *n1, int *n2) { printf("Values: %d and %d", *n1, *n2); } (B) CS1010 (AY2013/4 Semester 1)
10. Ex #2: Volume, Surface Area (1/2) • Write a program to read the length, width and depth (all integers) of a cuboid and compute (1) its volume, and (2) its surface area. • You are to write 2 versions and compare them: • Week6_Cuboid_v1.c: Include 2 functions volume(…) and surface_area(…) to compute the volume and surface area of the cuboid separately. • Week6_Cuboid_v2.c: Includea single function volume_and_surface_area(…) to compute both the volume and surface area of the cuboid. • There should be no printf() statement in your functions (apart from the main() function). depth width length CS1010 (AY2013/4 Semester 1)
10. Ex #2: Volume, Surface Area (2/2) • Sample runs Enter length, width and depth: 6 3 10 Volume = 180 Surface area = 216 Enter length, width and depth: 15 14 12 Volume = 2520 Surface area = 1116 CS1010 (AY2013/4 Semester 1)
11. Ex #3: Triangle Centroid (Take-home) (1/2) • In a triangle, a median is a line that connects a vertex to the midpoint of its opposite side. (eg: blue dotted lines) • The intersection of the 3 medians is called the centroid. (eg: point G) P (x1, y1) • Write a programWeek6_Centroid.c to read in the coordinates (of type float) of 3 vertices of a triangle and compute the coordinates of its centroid. • Your program should have a function centroid(…). • There should be no printf() statement in this centroid() function. • This is your take-home exercise. • This exercise is mounted on CodeCrunch. G R (x3, y3) Q (x2, y2) CS1010 (AY2013/4 Semester 1)
11. Ex #3: Triangle Centroid (Take-home) (2/2) • Sample runs Coordinates of 1st vertex: 0 0 Coordinates of 2nd vertex: 0 1 Coordinates of 3rd vertex: 1 1 Coordinates of centroid = (0.33, 0.67) Coordinates of 1st vertex: 4.8 12.7 Coordinates of 2nd vertex: -12.3 8.2 Coordinates of 3rd vertex: -5.6 15.3 Coordinates of centroid = (-4.37, 12.07) CS1010 (AY2013/4 Semester 1)
Summary for Today • Today’s most important lesson • Functions that “return” more than one value, through passing the addresses of variables into the functions CS1010 (AY2013/4 Semester 1)
Announcements/Things-to-do • Read Chapter 5 Functions • Do Take-home Lab #3 • PE1 this Saturday! • Refer to module website (“PE” page) for more information, such as venues, seating plan, etc.http://www.comp.nus.edu.sg/~cs1010/3_ca/pe.html • Next week: • Recess No class! • Next lecture (after the recess): • Revision and Arrays (Chapter 6 Numeric Arrays) CS1010 (AY2013/4 Semester 1)