Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 5 Functions, variable scope & pointers Structured Programming Instructor: Prof. K. T. Tsang 1.

Similar presentations


Presentation on theme: "Lecture 5 Functions, variable scope & pointers Structured Programming Instructor: Prof. K. T. Tsang 1."— Presentation transcript:

1 Lecture 5 Functions, variable scope & pointers Structured Programming Instructor: Prof. K. T. Tsang 1

2 Introduction to Functions A complex problem is often easier to solve by dividing it into several smaller parts, each of which can be solved by itself. This is called top-down programming. These parts are called functions in C/C++ (sometimes called subprograms). main() then executes these functions so that the original problem is solved. 2

3 Example : find all prime numbers < N For all integers 2<n<N Begin loop – test if n is a prime number End loop 3

4 Advantages of Functions Functions separate the concept (what is done) from the implementation (how it is done). Functions make programs easier to understand. Functions make programs easier to modify. Functions can be called several times in the same program, allowing the code to be reused. 4

5 Functions (p. 24 K&R) - encapsulation of commonly used block of codes - reusable “main” is a special function called (by the OS) at the beginning of the program. All other functions are called directly or indirectly from “main”. Function prototype: “return_type” function_name( arg1, arg2, …) Example: int power( int, int);OR int power( int m, int n); Arguments Parameters Inputs 5

6 Example : find all prime numbers < N Define a function int IsPrime(int n) 6

7 Example : find all prime numbers < N For all integers 2<n<N Begin loop – int ip= IsPrime(n) – if (ip=0) n is not a prime – if (ip=1) n is a prime End loop 7

8 C/C++ Functions C allows the use of both internal (user-defined) and external functions. External functions (e.g. printf(), getchar(), putchar(), etc.) are usually grouped into specialized libraries (e.g., stdio, string, math, etc.) 8

9 Mathematical Functions #include double log(double x) natural logarithm double log10(double x) base 10 logarithm double exp(double x) e to the power x double pow(double x, double y) x to the power y double sqrt(double x) positive square root of x double ceil(double x) smallest integer not less than x double floor(double x) largest integer not greater than x double sin(double x), cos(double x), tan(double x), etc... 9

10 Distance Between Two Points /* Compute distance between two points */ #include #include /* contains sqrt() */ int main(){ double x1, y1, x2, y2; /* coordinates for point 1 & 2 */ double dist; /* distance between points */ /* input the coordinates for point 1 & 2 */ x1 = 0.0; y1 = 0.0; x2 = 9.0; y2 = -7.5; /* Compute the distance between points 1 & 2 */ dist = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); printf ("The distance is %f\n“, dist); return 0; } 10

11 Functions in a Program C/C++ programs usually have the following form: include statements function prototypes main() function user-defined functions 11

12 Function Prototype The function prototype declares the interface, or input and output parameters of the function, leaving the implementation for the function definition. The function prototype has the following syntax: ( ); Example: A function that prints the page/pages in a document given the page number (e.g. 7) as input: void print_page(int); Orvoid print_page(int from, int to); (This is a void function - a function that does not return a value) 12

13 Function Definition The function definition can be placed anywhere in the program after the function prototypes. You can place a function definition in front of main(). In this case there is no need to provide a function prototype for the function, since the function is already defined before its use. A function definition has following syntax: ( ){ } 13

14 Function Call A function call with return has the following syntax: variable_name = ( ); There is a one-to-one correspondence between the parameters in a function call and the parameters in the function definition. variable_name must be compatible with function return type. For void function, there is nothing to return: ( ); 14

15 Example: Adding two numbers Consider the following function prototype: int add(int a, int b); We might call the function using the syntax: int main(){ int sum; sum = add(5, 3); return 0; } Define the function as follows int add(int a, int b){ int result = a+b; return result; } This would result in variable sum being assigned the value 8. 15

16 If the function is defined in front of main, function prototype is not needed. int add(int a, int b){ int result = a+b; return result; } int main(){ int sum; sum = add(5, 3); return 0; } 16

17 #include int add(int a, int b){ int result = a+b; return result; } int main(){ int sum, a=5, b=3; sum = add(a, b); printf(“The sum of %d and %d is %d\n”, a, b, sum); return 0; } 17

18 Arguments – passed by value 数值传值 C/C++ function arguments are passed “by value”, temporary variables are created inside the function to accept the values given the callers. The original variables in the caller that hold those values are not affected. In other languages, function arguments may be passed “by reference” 参考传值, in which the called function has access to the original argument, not a local copy. Example: p. 24 K&R 18

19 Pass by Value: Example For example, consider the following code: int sum(int a, int b){ a = a + b; return a; } void main(){ int x, y, z; x = 3; y = 5; z = sum(x,y); } What are the values of x, y, and z at the end of the main() program? 19

20 Pass by Value: Example The answer: 3, 5, and 8. Even though the value of parameter a is changed, the corresponding value in variable x does not change. This is why this is called pass by value. The value of the original variable is copied to the parameter, but changes to the value of the parameter do not affect the original variable. In fact, all information in local variables declared within the function will be lost when the function terminates. The only information saved from a pass by value function is in the return statement. 20

21 Passing Parameters by Reference 参考传值 To have a function with multiple outputs, we have to use pass by reference. Reference (address) of parameter is passed to the function, instead of its value. If the function changes the parameter value, the changes will be reflected in the program calling it. How to pass parameters by reference: &,..., & 21

22 22 Pass by Reference passes in a reference to a variable - this is effectively the address of the variable into the function. This is considerably more efficient than by value and allows the function to change the variable directly, something only possible in C by passing in a pointer to the variable.

23 Reference (引用,参考) is an alias (外号) Reference serves as an alternative name for a variable. It is a compound type defined by preceding a variable name by the & symbol. A compound type is defined in term of another type. Each reference type refers to another type. We cannot have reference to another reference type. int ival = 234; int &refVal = ival;//ok int &refVal1;//error: reference must be initialized int &refVal2 = 10;//error: must initially refer to a variable refVal = 10;//ok, but ival also changed int &r1 = ival, r2 = ival;//ok, r1 is int&, r2 is an int int &r3 = r1; //error: reference to another reference not allowed 23

24 Pass by Reference: Example 1a If the argument of the function is a reference type: #include void Increment(int& Number){ Number = Number + 1; printf("The parameter Number: %d”, Number); } void main(){ int I = 10; Increment(I); //input parameter is variable I printf("The variable I is:%d”,I); } The variable passed in the calling program will be changed. 24

25 Pass by Reference: Example 1b Now try this function defined slightly different. What are the printf outputs? #include void Increment(int Number){ Number = Number + 1; printf("The parameter Number: %d”, Number); } void main(){ int I = 10; Increment(I); //input parameter is variable I printf("The variable I is:%d”,I); } 25

26 Pass by Reference: Example 2 It is possible to use both pass by reference and pass by value parameters in the same function. // Print the sum and average of two numbers // Input: two numbers x & y // Output: sum - the sum of x & y // average - the average of x & y #include void SumAve (double, double, double&, double&); 26

27 Pass by Reference: Example 2 void main ( ) { double x=5, y=15, sum, mean; SumAve (x, y, sum, mean); printf("The inputs are %f %f\n”, x, y); printf("The sum is %f\n”, sum); printf("The average is %f\n”, mean); } void SumAve(double no1, double no2, double& sum, double& average) { sum = no1 + no2; average = sum / 2; no1++; no2++; } 27

28 Pass by Reference: Example 3 // sort three integers #include void swap (int&, int&); void main ( ) { int n1=55, n2=122, n3=43; // input integers printf("The input integers are %d %d %d\n”, n1,n2,n3); if (n1> n2) swap (n1, n2); if (n2> n3) swap (n2, n3); if (n1> n2) swap (n1, n2); printf("The sorted integers are %d %d %d\n”, n1,n2,n3); } 28

29 Pass by Reference: Example 3 //Function for swapping two integers void swap (int& x, int& y) { int temp; temp = x; x = y; y = temp; } 29

30 Pass by Reference: scanf #include void main(){ int a,b,c; printf("input a,b,c\n"); scanf("%d, %d, %d", &a, &b, &c); printf("a=%d, b=%d, c=%d\n", a, b, c); } 30

31 Pass by Reference: scanf #include void main(){ int a,b,c; printf("input a,b,c\n"); scanf("%d, %d, %d", &a, &b, &c); printf("a=%d, b=%d, c=%d\n", a, b, c); } 31

32 Pass by Reference: scanf #include void main(){ int i; printf("input an integer\n"); if(scanf("%d", &i) == 1) printf("input integer %d\n", i); else printf("scanf input error\n"); } 32

33 Since “scanf” does not skip white space, it is easy to detect the end of a line: char ch; do { scanf(“%c”, &ch); printf(“%c”, ch); } while (ch != ‘\n’); “scanf” is more versatile than “getchar”, which can read one character only then return it. ch = getchar(); 33

34 #include int isPrime(int n) { int div; if(n<=1) return 0; if(n==2) return 1; for(div=2; div*div<=n; div++) if(n%div == 0) return 0; return 1; } void main(){ int i; printf("input an integer\n"); if(scanf("%d", &i) != 1) {printf("input error\n"); return;} printf("input integer is %d\n", i); if(isPrime(i)) printf(“prime\n”); else printf(“not a prime\n”); return; } 34

35 Pass by value int funcA(int i1, char c1, float f1); main(){ int i2, i3; char c2; float f2; … i3 = funcA( i2, c2, f2 ); … } int funcA(int i1, char c1, float f1){ … } Values are copied and passed from local variables i2, c2 & f2 in main to newly created local variables i1, c1 & f1 in funcA 35

36 Pass by reference int funcB(int& i1, char& c1, float& f1); main(){ int i2, i3; char c2; float f2; … i3 = funcB( i2, c2, f2 ); … } int funcB(int& i1, char& c1, float& f1){ … } Local variables i1, c1 & f1 in funcB are created as references to local variables i2, c2 & f2 in main. When i1, c1 & f1 are changed in funcB, i2, c2 & f2 in main are changed as well. 36

37 Local variables (p. 31 K&R) Variables declared within a block of code are private or local to the specific block of code. Local variables (also known as automatic variables) exist only when that block of code is called and disappear when that block of code is exited. “block of code” includes inside a function, a loop or if statement. 37

38 Scope of an identifier The scope of a declaration is the block of code where the identifier is valid to use. –A global declaration is made outside the bodies of all functions and outside the main program. It is normally grouped with the other global declarations and placed at the beginning of the program file. –A local declaration is one that is made inside the body of a function. Locally declared variables cannot be accessed outside of the function they were declared in. –It is possible and legal to declare the same identifier name in different parts of the program. However, it is not a good practice because it can be confusing. 38

39 Caution! Undisciplined use of global variables may lead to confusion and debugging difficulties. Instead of using global variables in functions, try passing local variables by reference. 39

40 External variables – defined outside of all functions so that the compiler can set up a global storage for them. If a function wants to have access of an external variable, it must declare with an explicit extern keyword. Examples: p. 32 K&R max, line and longest are defined globally. In main, we have extern declaration for max & longest before using them. In function getline, extern declaration for line. In function copy, extern declaration for line & longest. 40

41 Scope of a variable – the block of code where the variable is defined int global_var; int functionA(void); main() { int local_var; … {/*beginning of a new block*/ float very_local_var; … }/*end of new block*/ … } int functionA(void) { extern int global_var; global_var = 12; … } 41

42 Declaration & definition of variables Definition of a variable causes a compiler to set aside memory at compile time. Declaration makes known the type and name of a variable to a function. A name (identifier) is declared without being defined by using the extern keyword. An extern declaration does not allocate memory. A variable can be declare multiple times, but must be defined only once. 42

43 Global & local variables Global variable -- When a variable is introduced outside of any function body, the compiler will set aside memory for the variable at compile time. It is both declared and defined. Local variable -- When a variable is introduced inside a function body, the compiler does not set aside memory for the variable at compile time. It is only declared. Memory will be allocated for this variable only at run-time. After the function is exited memory for the variable will be de-allocated. 43

44 Note (p.33 K&R) If the definition of an external variable appears before its use in a particular function in the same source file, there is no need for an extern declaration in the function. If the program is in more than one file, a variable defined in file1 and used in file2 & file3, then extern declarations are needed in file2 & file3 before the use of that variable. 44

45 Scope of Global Variables Global variables in a single-file program are available to all functions defined after these variables are defined, except in functions with local variables with the same name. Such local variables are said to shadow the corresponding global variables. Global variables are valid everywhere. Local variables are only valid inside the {} where they are defined. 45

46 Shadowing of global variable 46

47 Scope: Example 5 int A,B,C,D; void Two(int A, int B, int& D) { B = 21; D = 23; cout <<A<< " " <<B<< " " <<C<< " " <<D<< endl; } void One(int A, int B, int& C) { int D; // Local variable A = 10; B = 11; C = 12; D = 13; cout <<A<< " " <<B<< " " <<C<< " " <<D<< endl; Two(A,B,C); } void main() { A = 1; B = 2; C = 3; D = 4; One(A,B,C); cout <<A<< " " <<B<< " " <<C<< " " <<D<< endl; Two(A,B,C); cout <<A<< " " <<B<< " " <<C<< " " <<D<< endl; } 47

48 Scope: Example 5 Output: 10 11 12 13 10 21 23 23 1 2 23 4 1 21 23 23 1 2 23 4 Convince yourself that this is the right answer. This example demonstrates the shadowing of global variables by local variables. 48

49 Summary Prototyping & defining a function Passing parameters (call) by value vs. by reference Scope of a variable Local vs. global variables Declaring vs. defining variables Compile-time vs. run-time allocation of memory 49

50 Address Operator & #include void main(){ int a, b; a = 88; b = 100; printf("The address of a is: %x”, &a); printf("The address of b is: %x”, &b); } Try the following code to get the addresses of variables. Address is usually a large number, so print it in hex. 50

51 Pointer 指针 A pointer 指针 is a variable used for storing the address of a memory location. Using pointer, we can access the value of the variable stored in the specified memory location indirectly. 51

52 Pointer Types C/C++ has pointer types for each type of data, e.g. Pointers to int data type Pointers to char data type Pointers to user-defined data structure Even pointers to pointers Pointers to pointers to int type 52

53 Pointer Variables A pointer variable is a specific box for storing a memory address Declaration of Pointer variables type* pointer_name; //style 1 or type *pointer_name; //style 2 or type * pointer_name; //style 3 where type is the type of data pointed to (e.g. int, char, double) by the pointer. 53

54 Declaration of Pointers The style 2 (in previous slide) is more popular because it is more convenient to have multiple declaration, and accessing the target value, e.g. int* p1; int *p2; int * p3; int i1, i2, *ip; //ip is a pointer ip = &i1; //initialize ip by address of i1 *ip = 23; //assign 23 to i1 float f1 = 1.33; ip = &f1; //error, why? 54

55 Pointer Variables int a = 100; int *p = &a; printf(“%d %x\n”, a, &a); printf(“%x %x\n”, p, &p); The value of pointer p is the address of variable a. A pointer is also a variable, so it has its own memory address. 10088…1024… Memory address:0x10240x1034… 0x1020 ap 55

56 De-reference Operator * 取值算符 We can access to the value stored in the variable pointed to by preceding the pointer with the dereference (indirection) operator (*), int a = 100; int *p = &a; printf(“%d %x\n”, a, &a); printf(“%d %x %x\n”, *p, p, &p); 10088…1024… Memory address:0xa23b0xa24b… ap Result is: 100 a23b 100 a23b a24b 56

57 Example: * operator int numberA, *p, m; numberA = 145; p = &numberA;//initialize p m = *p;//assign 145 to m *p = 31;//assign 31 to variable pointed to by p printf(“%d\n”, numberA );//31 57

58 Don ’ t get confused Declaring a pointer means only that it is a pointer: int *p; //p is an integer pointer While the de-reference operator is also expressed by the asterisk character( * ), they are simply two different tasks represented with the same symbol int a = 100, b = 88, c = 8; int *p1 = &a, *p2, *p3 = &c; p2 = &b;// p2 points to b p1 = p2; // p1 points to b b = *p3;//assign c to b printf(“%d%d%d\n”, a, b, c); //result is: 888 58

59 Pointer Example #include int main (){ int value1 = 5, value2 = 15; int *p1, *p2; p1 = &value1; // p1 = address of value1 p2 = &value2; // p2 = address of value2 *p1 = 10; // value pointed to by p1=10 *p2 = *p1; // value pointed to by p2= value // pointed to by p1 printf("value1=%d ; value2=%d\n“, value1, value2); p1 = p2; // p1 = p2 (pointer value copied) *p1 = 20; // value pointed to by p1 = 20 printf("value1=%d ; value2=%d\n“, value1, value2); return 0; } Result is: value1=10 ; value2=10 value1=20 ; value2=20 59

60 Pointer to other pointer Pointer variable has its own address. So we can define a pointer points to another pointer. int ival = 67; int *p = &ival; //pointer to ival int **q; // declaring a pointer to other pointer q = &p;//pointer to pointer p 60

61 Pointer to Pointer What is the output? 58 58 58 61

62 62 void foo (int* a) { int x = 3; *a = x; } int main() { int a; foo(&a); return 0; } int main() { int* a; foo(a); return 0; } //segmentation fault error Pointer as function arguments: void foo1 (int& a) { int x = 3; a = x; } int main() { int a; foo1(a); return 0; }

63 63 #include //C++ void swap(int& i, int& j) { int temp = i; i = j; j = temp; } int main(void) { int a = 10; int b = 20; swap(a, b); printf(“a= %d b= %d\n", a, b); return 0; } #include //C void swap1(int *i, int *j) { int temp = *i; *i = *j; *j = temp; } int main(void) { int a = 10; int b = 20; swap1(&a, &b); printf(“a= %d b= %d\n", a, b); return 0; } Compare this with call by reference example: swap

64 64 #include void swapint(int *i, int *j) { int temp = i; i = j; j = temp; } int main(void) { int a = 10; int b = 20; swapint(&a, &b); printf(“a=%d b=%d\n", a, b); return 0; } Exercise: what will happen if the following program is executed?

65 Recursion: 重叠算法 Recursion is one way to decompose a task into smaller subtasks. At least one of the subtasks is a smaller example of the same task. The smallest example of the same task has a non-recursive solution. Example: The factorial function n! = n * (n-1) * (n-2) *... * 1 or n! = n * (n-1)! and 1! = 1 65

66 Recursion is like Russian Dolls 66

67 Recursion 重叠算法 : Example #include int fac(int n){// Assume n >= 0 int product; if(n <= 1) return 1; product = n * fac(n-1); return product; } void main(){// driver function int number; do{ printf ("Enter integer (negative to stop)”); scanf(“%d”, &number); if(number >= 0) printf(“%d\n”, fac(number)); }while(number >= 0); } 67

68 Iterative (屡进,递增) Factorial // Non-recursive factorial function // Compute the factorial using a loop int fac(int n){ // Assume n >= 0 int k, product; if(n <=1) return 1; product = 1; for(k=1; k<=n; k++) product*= k; return product; } 68

69 Recursion: Example 1 How to calculate exp(int x, int y) recursively? int exp(int x, int y){ if(y==0) return 1; return x * exp(x, y-1); } 69

70 Other Recursive example Fibonacci numbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34,... where each number is the sum of the preceding two. Recursive definition: –F(1) = 1 –F(0) = 0 –F(n) = F(n-1) + F(n-2) 70

71 Recursion: Example 4 Write a recursive function that counts the number of zero digits in a non-negative integer Example: zeros(10200) returns 3 int zeros(int n){ if(n==0) return 1; if(n < 10) return 0; if(n%10 == 0) return 1 + zeros(n/10); else return zeros(n/10); } 71

72 Recursion: Example 5 Write a recursive function to determine how many factors m are part of n. For example, if n=48 and m=4, then the result is 2 (48=4*4*3). int factors(int n, int m){ if(n%m != 0)return 0; return 1 + factors(n/m, m); } 72

73 Summary Recursion is a special way to decompose a task into smaller subtasks. At least one of the subtasks is a smaller example of the same task. The smallest example of the same task has a non-recursive solution. 73


Download ppt "Lecture 5 Functions, variable scope & pointers Structured Programming Instructor: Prof. K. T. Tsang 1."

Similar presentations


Ads by Google