350 likes | 468 Views
CS1010: Programming Methodology http://www.comp.nus.edu.sg/~cs1010/. Week 6: Modular Programming. Objectives: Understand how to use function to pass back more than one value Understand how to use header files and separate compilation to make your program modular References:
E N D
CS1010: Programming Methodologyhttp://www.comp.nus.edu.sg/~cs1010/
Week 6: Modular Programming • Objectives: • Understand how to use function to pass back more than one value • Understand how to use header files and separate compilation to make your program modular • References: • Chapter 5: Lessons 5.4 – 5.5 (Functions that “return” more than one value) • Chapter 8: Data Structures and Large Program Design CS1010 (AY2011/2 Semester 1)
Outline 0. Week 5 Exercise 4: Prime Number • Functions Revisit • Pointer Variables • Functions with ¶meters • Exercise #1: Code tracing • Modularization and Interfaces • Separate Compilation • Exercise #2: Modularize “Draw Stick Figures” problem with separate programs Topics 5 – 7 are non-examinable. CS1010 (AY2011/2 Semester 1)
0. 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 function is_prime(int). • Sample runs: Enter a positive integer: 131 131 is a prime. Enter a positive integer: 713 713 is not a prime. CS1010 (AY2011/2 Semester 1)
1. 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 “void func ( … ) { … };” • One output through, e.g., “double func ( … ) { …; return value; };” • More outputs through changing input values • ‘&’– ‘address of’ operator • ‘*’– ‘indirection’ operator; go to the address stored in the variable following the * to get the/put a value at that address • We have done void functions and functions that return a single value, how about functions that return more than one value? CS1010 (AY2011/2 Semester 1)
1. Functions: Revisit (2/3) • But a function can return only one value! • What is the output of this program? #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)); return 0; } int f(int x, int y, int z) { return x; return y; return z; } CS1010 (AY2011/2 Semester 1)
1. Functions: Revisit (3/3) • What if we really need to “return” more than one value? • 2 possible approaches • Returning a collection of data (eg: array, structure) – we will discuss this another time • Use variables to hold these values, and pass the addresses of these variables to the functions • This involves the use of & (address operator) and * (indirection operator) (also known as the dreaded pointer) CS1010 (AY2011/2 Semester 1)
2. Pointer Variables (1/4) • A pointer variable stores the address of another variable • C provide 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 an integer variable p = &i; // p now stores the address of variable i printf("value of i is %d\n", *p); value of i is 10 Now *p is equivalent to i CS1010 (AY2011/2 Semester 1)
2. Pointer Variables (2/4) 12 12 inti = 10, j = 20; int *p; // p is a pointer to an integer 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 p = &j; // p now stores the address of variable j *p = i; // value of *p (which is j now) becomes 12 CS1010 (AY2011/2 Semester 1)
2. Pointer Variables: Demo #1 (3/4) • Week6_Pointers.c What is the output? #include <stdio.h> int main(void) { double a, *b; b = &a; *b = 12.34; printf("%f\n", a); return 0; } CS1010 (AY2011/2 Semester 1)
2. Pointer Variables: Common Mistake (4/4) #include <stdio.h> int main(void) { int *n; *n = 123; printf("%d\n", *n); return 0; } • Week6_Pointers_Common_Mistake.c What’s wrong with this? CS1010 (AY2011/2 Semester 1)
3. 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 (AY2011/2 Semester 1)
3. Functions with ¶meters (2/6) // Week6_FunctionDemo2.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 (AY2011/2 Semester 1)
3. 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); 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); } CS1010 (AY2011/2 Semester 1)
3. 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); } CS1010 (AY2011/2 Semester 1)
3. 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); return 0; } 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? CS1010 (AY2011/2 Semester 1)
3. Functions with ¶meters (6/6) • Can you correct the previous program? (Answer will be shown in class.) CS1010 (AY2011/2 Semester 1)
4. 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) { int a = 5; double b = 7.1; int c = 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); return 0; } CS1010 (AY2011/2 Semester 1)
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 intvalue; double sum; int main(void) { . . . } This is a constant, not a global variable. These are global variables. CS1010 (AY2011/2 Semester 1)
5. 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 • Need to be able to “break” the program into multiple modules (files) • Need to be able to separately compile modules • Need to be able to link all modules into an executable Executable code produces Compiler a.out eg: gcc welcome.c CS1010 (AY2011/2 Semester 1)
5. 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 signature of a method (its return type, name and parameter list) constitutes theinterface (header file). The body of the function (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 (AY2011/2 Semester 1)
5. 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 (AY2011/2 Semester 1)
6. Separate Compilation • A module contains in most cases 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 (AY2011/2 Semester 1)
6.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 (AY2011/2 Semester 1)
6.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: Week6_FreezerTemp.h • Module source file: Week6_FreezerTemp.c // Compute new temperature in freezer floatcalc_temperature (floathours_float); #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 (AY2011/2 Semester 1)
6.1 Demo #2: Main Module #include <stdio.h> #include "Week6_FreezerTemp.h" int main (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); return 0; } Now we can write aprogram which uses our new external function: File Week6_FreezerMain.c CS1010 (AY2011/2 Semester 1)
6.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 (AY2011/2 Semester 1)
6.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 (AY2011/2 Semester 1)
6.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 (AY2011/2 Semester 1)
6.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 (AY2011/2 Semester 1)
6.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 mistype a function name. CS1010 (AY2011/2 Semester 1)
7. Exercise #2 • Take the Week 3 Exercise #4 of drawing stick figures to the screen and put all the drawing functions into a separate module. • Create a separate module • Week6_DrawingFunctions.c (and Week6_DrawingFunctions.h) • Change the main module to use the external module functions. Call it Week6_DrawFigures.c • Compile, link and test your program. CS1010 (AY2011/2 Semester 1)
Summary for Today • Today’s most important lessons • Functions that “return” more than one value, through passing the addresses of variables into the functions • Modularization and Interfaces • Structure your program into separate modules, each containing a set of related functions and data structures. CS1010 (AY2011/2 Semester 1)
Announcements/Things-to-do • Read Chapter 8 Data Structures and Large Program Design • Do Take-home Lab #3 (to be released later this week) • PE1 this Saturday! • Refer to module website (“Labs” page) for more information, such as venues, seating plan, etc. • Next week: • Recess No class • Next lecture (after the recess): • Revision and Arrays (Chapter 6 Numeric Arrays) CS1010 (AY2011/2 Semester 1)
End of File CS1010 (AY2011/2 Semester 1)