1 / 55

CS1010: Programming Methodology comp.nus.sg/~cs1010/

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

carlyn
Download Presentation

CS1010: Programming Methodology comp.nus.sg/~cs1010/

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS1010: Programming Methodologyhttp://www.comp.nus.edu.sg/~cs1010/

  2. 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 (only for reading, non-examinable) CS1010 (AY2012/3 Semester 1)

  3. Outline (1/2) • Week 5 Exercise 4: Prime Number • Testing and Debugging (only for reading) • Functions Revisit • Pointer Variables 4.1 Demo #1 4.2 Common Mistake • Functions with &parameters • Exercise #1: Code tracing • Warning! Global Variables • Modularization and Interfaces (only for reading) • Separate Compilation (only for reading) Topics 2, 8 and 9 are non-examinable. CS1010 (AY2012/3 Semester 1)

  4. Outline (2/2) • Quizzes • Exercise #2: Volume and Surface Area of Cuboid • Exercise #3: Triangle Centroid (take-home) CS1010 (AY2012/3 Semester 1)

  5. 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 (AY2012/3 Semester 1)

  6. 2. Testing and Debugging (1/8) • (Section 2 is only for your reading. You may try out the gdb debugger on your own.) • The previous exercise shows the importance of testing. • Where does the term “debugging” come from? • Very early computers used mechanical relays for switching currents. However, most likely the termbug existed beforethe “moth-in-a-relay”story. • Why does a program “core dump”? • Early computers usedtiny magneticcores (rings) asmemory cells to hold0 and 1 values. Moveable armature Electro-magnet Notebook with moth fromMark II computer: Space (Bugs may get stuck here!) CS1010 (AY2012/3 Semester 1)

  7. Testing Debug Error? Yes 2. Testing and Debugging (2/8) • Testing • To determine if a code contains errors. • Debugging • To locate the errors and them. • Documentation • To improve maintainability of the code. • Include sensible comments, good coding style and clear logic. CS1010 (AY2012/3 Semester 1)

  8. 2. Testing and Debugging (3/8) • Philosophical notes on program design, debugging and testing • A good design is importantA good design results in a high quality program. A low quality design cannot be “debugged into” high quality. • Don’t optimize for speed too earlyIt is possible to make a correct program run faster.It is much more difficult to make a fast (but wrong) program run correctly. CS1010 (AY2012/3 Semester 1)

  9. 2. Testing and Debugging (4/8) • A program should be tested with various input values to make sure that it performs correctly across all inputs. • A program should make as few assumptions about the input as possible. • E.g.: Your program assumes that the user will type a number. But she types a string  crash! • However, in CS1010 we assume that input follows the specification. We do this to focus on the basics first. Writing robust programs is not trivial. • Many of today’s methods to hack into computers work by feeding programs with unexpected inputs. This results in crashes, buffer overflows, etc. CS1010 (AY2012/3 Semester 1)

  10. 2. Testing and Debugging (5/8) How to test? • By user/programmer: • Run program by hand multiple times. • By test program: • Write a little test program that runs the program to be tested with different inputs. • By test environments: • Large-scale test suites that generate test cases, run them, compare the expected output and provide a pass/fail assessment. CS1010 (AY2012/3 Semester 1)

  11. 2. Testing and Debugging (6/8) • Manual walkthroughs • Tracing with pencil-and-paper • Verbal walkthroughs • printf() statements • Easy to add • Provide information: • Which functions have been called • The value of parameters • The order in which functions have been called • The values of local variables and fields at strategic points • Disadvantages • Not practical to add printf() statements in every function • Too many printf() statements lead to information overload • Removal of printf() statements tedious CS1010 (AY2012/3 Semester 1)

  12. 2. Testing and Debugging (7/8) • Tips and Techniques • Start off with a working algorithm • Incremental coding/test early/fix bugs as you find them • Simplify the problem • Explain the bug to someone else • Recognize common errors (such as using ‘=’ instead of ‘==’, wrong addition of semi-colon, infinite loop, etc.) • Recompile everything (referring to a suite of programs) • Test boundaries • Eg: For primality test (Week 5 Exercise 4), did you test your program with the value 1? 2? • Test exceptional conditions • Take a break! CS1010 (AY2012/3 Semester 1)

  13. 2. Testing and Debugging (8/8) • Test your programs with your own data • Do not rely on CodeCrunchto test your programs! • We discussed this in week 4. There is an error in this code: // To find the maximum among 3 integer// values in variables num1, num2, num3.int max = 0;if((num1 > num2) && (num1 > num3)) max = num1;if((num2 > num1) && (num2 > num3)) max = num2;if((num3 > num1) && (num3 > num2)) max = num3; • It works fine if it is tested on some sets of data: <3,5,9>, <12,1,6>, <2,7,4>, etc. • But what test data are missing? CS1010 (AY2012/3 Semester 1)

  14. 2.1 Using the gdb Debugger (1/2) • Debugger usually provides the following • Stepping • Breakpoint • Watches (inspecting variables) • We will illustrate these with Gnu debugger gdb. • See video http://www.youtube.com/watch?v=Z6zMxp6r4mc CS1010 (AY2012/3 Semester 1)

  15. 2.1 Using the gdb Debugger (2/2) • Step 1: add the –g option when compiling and linking: • gcc –g Week8_WashersWeight_Printf.c • Step 2: start the gdb with your program: • gdba.out • Step 3: use the different gdb commands to step through your program: • Break at a specific function: break function_name • Start with: break main • Run program: run (or r) • Step to the next line of code: step (or s) • List source code: list (or l) • Examine the value of a variable: print variable_name • Quit the debugger: quit Explore other gdb commands on your own! CS1010 (AY2012/3 Semester 1)

  16. 2.2 Famous Programming Errors • Mariner Bugs Out (1962) • Cost:  $18.5 million • Disaster:  The Mariner 1 rocket with a space probe headed for Venus diverted from its intended flight path shortly after launch.  Mission Control destroyed the rocket 293 seconds after liftoff. • Cause:  A programmer incorrectly transcribed a handwritten formula into computer code, missing a single superscript bar.  Without the smoothing function indicated by the bar, the software treated normal variations of velocity as if they were serious, causing faulty corrections that sent the rocket off course. • Mars Climate Crasher (1998) • Cost:  $125 million • Disaster:  After a 286-day journey from Earth, the Mars Climate Orbiter fired its engines to push into orbit around Mars.  The engines fired, but the spacecraft fell too far into the planet’s atmosphere, likely causing it to crash on Mars. • Cause:  The  software that controlled the Orbiter thrusters used imperial units (pounds of force), rather than metric units (Newtons) as specified by NASA. CS1010 (AY2012/3 Semester 1)

  17. 3. 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 (AY2012/3 Semester 1)

  18. 3. 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 (AY2012/3 Semester 1) 

  19. 3. 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) CS1010 (AY2012/3 Semester 1)

  20. 4. 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 Now *p is equivalent to i CS1010 (AY2012/3 Semester 1)

  21. 4. 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 (AY2012/3 Semester 1)

  22. 4.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 (AY2012/3 Semester 1) 

  23. 4.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 (AY2012/3 Semester 1)

  24. 4.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 (AY2012/3 Semester 1) 

  25. 5. Functions with &parameters (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 (AY2012/3 Semester 1) 

  26. 5. Functions with &parameters (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 (AY2012/3 Semester 1) 

  27. 5. Functions with &parameters (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 (AY2012/3 Semester 1) 

  28. 5. Functions with &parameters (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 (AY2012/3 Semester 1) 

  29. 5. Functions with &parameters (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 (AY2012/3 Semester 1)

  30. 5. Functions with &parameters (6/6) • Can you correct the previous program? (Answer will be shown in class.) CS1010 (AY2012/3 Semester 1) 

  31. 6. 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 (AY2012/3 Semester 1) 

  32. 7. 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 (AY2012/3 Semester 1)

  33. 8. 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 (AY2012/3 Semester 1)

  34. 8. 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 (AY2012/3 Semester 1)

  35. 8. 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 (AY2012/3 Semester 1)

  36. 9. 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 (AY2012/3 Semester 1)

  37. 9.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 (AY2012/3 Semester 1)

  38. 9.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 (AY2012/3 Semester 1)

  39. 9.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 (AY2012/3 Semester 1)

  40. 9.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 (AY2012/3 Semester 1)

  41. 9.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 (AY2012/3 Semester 1)

  42. 9.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 (AY2012/3 Semester 1)

  43. 9.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 (AY2012/3 Semester 1)

  44. 9.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 (AY2012/3 Semester 1)

  45. 10. 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 (AY2012/3 Semester 1) 

  46. 10. 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 (AY2012/3 Semester 1) 

  47. 10. 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 (AY2012/3 Semester 1) 

  48. 10. 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 (AY2012/3 Semester 1) 

  49. 11. 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 (AY2012/3 Semester 1)

  50. 11. 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 (AY2012/3 Semester 1)

More Related