KỸ THUẬT LẬP TRÌNH (p6) doc

9 115 0
KỸ THUẬT LẬP TRÌNH (p6) doc

Đang tải... (xem toàn văn)

Thông tin tài liệu

0 K K Ỹ Ỹ THU THU Ậ Ậ T L T L Ậ Ậ P TRÌNH P TRÌNH KỸ THUẬT PHÁT TRIỂN CHƯƠNG TRÌNH NỘI DUNG  Hàm và Thủ tục  Phát triển chương trình bằng phương pháp tinh chỉnh dần từng bước.  Định nghĩa và sử dụng hàm trong ngôn ngữ C  Hàm đệ quy 1 Đ Đ ị ị nh ngh nh ngh ĩ ĩ a v a v à à s s ử ử d d ụ ụ ng h ng h à à m trong C m trong C  Hàm trong C • Các Modules trong C • Một chương trình bao gồm các hàm do người sử dụng tạo dựng và các hàm thư viện – Thư viện chuẩn C có một lượng lớn các hàm và có thể được mở rộng thêm – V ídụ: khi dùng #include <stdio.h>, ta có thể gọi hàm scanf,…  Lời gọi hàm • Xuất phát từ chương trình chính (main) hoặc từ 1 hàm nào đó. • Yêu cầu gọi các hàm: – Cung cấp tên hàm và các đối số – Hàm thực hiện các hành động hoặc các thao tác – Hàm trả lại kết quả 2  Ngữ nghĩa lời gọi hàm: – Giám đốc giao nhiệm vụ cần hoàn thành cho nhân viên – Nhân viên nhận thông tin, thực hiện, trả lại kết quả – Giám đốc không biết chi tiết về quá trình thực hiện main worker1 worker2 worker3 worker4 worker5 3  Cú pháp định nghĩa hàm return-value-type function-name( parameter-list ) { khai báo dữ liệu và các lệnh } • Function-name: Tên hàm • Return-value-type: kiểu dữ liệu c ủa kết quả trả về (mặc định là int) – void – hàm không trả lại kết quả • Parameter-list: các tham số cách nhau bằng dấu “,” – Phải khai báo kiểu dữ liệu cho từng tham số. 4  Cú pháp định nghĩa (tiếp theo) • Các khai báo và các lệnh: thân của hàm (khối) – Các biến có thể được định nghĩa bên trong hàm – Các hàm không được định nghĩa trong hàm khác • Kiểm soát kết quả trả về bằng lệnh return – Nếu không có kết quả trả về – return; – hoặc gặp dấu ngoặc móc } để kết thúc – Nếu có kết quả trả về – return biểu_thức; fig05_04.c (Part 1 of 2) fig05_04.c (Part 1 of 2) 1 /* Fig. 5.4: fig05_04.c 2 Finding the maximum of three integers */ 3 #include <stdio.h> 4 5 int maximum( int x, int y, int z ); /* function prototype */ 6 7 /* function main begins program execution */ 8 int main() 9 { 10 int number1; /* first integer */ 11 int number2; /* second integer */ 12 int number3; /* third integer */ 13 14 printf( "Enter three integers: " ); 15 scanf( "%d%d%d", &number1, &number2, &number3 ); 16 17 /* number1, number2 and number3 are arguments 18 to the maximum function call */ 19 printf( "Maximum is: %d\n", maximum( number1, number2, number3 ) ); 20 21 return 0; /* indicates successful termination */ 22 23 } /* end main */ 24 Enter three integers: 22 85 17 Maximum is: 85 Enter three integers: 85 22 17 Maximum is: 85 Enter three integers: 22 17 85 Maximum is: 85 25 /* Function maximum definition */ 26 /* x, y and z are parameters */ 27 int maximum( int x, int y, int z ) 28 { 29 int max = x; /* assume x is largest */ 30 31 if ( y > max ) { /* if y is larger than max, assign y to max */ 32 max = y; 33 } /* end if */ 34 35 if ( z > max ) { /* if z is larger than max, assign z to max */ 36 max = z; 37 } /* end if */ 38 39 return max; /* max is largest value */ 40 41 } /* end function maximum */ 7 Ph Ph ạ ạ m vi c m vi c ủ ủ a bi a bi ế ế n n Biến toàn cục và biến địa phương  Biến toàn cục: là những biến được sử dụng ở mọi nơi trong chương trình. • Cấp phát bộ nhớ cho biến toàn cục: cấp phát bộ nhớ tĩnh  Biến địa phương: là biến chỉ có giá trị trong thời gian hàm hoạt động, sau khi kết thúc hàm thì những biến khai báo bên trong hàm và các tham số truyền cho hàm sẽ không tồn tại nữa. 8  Cấp phát bộ nhớ cho biến địa phương: cấp phát tự động, cần đến đâu cấp phát đến đó, mỗi lần gọi hàm là một lần cấp phát.  Biến địa phương tĩnh static: Yêu cầu cấp phát các biến của hàm ở vị trí cố định, tĩnh tại, luôn được dùng cho hàm. Vì vậy, giá trị của các biến này có thể tồn tại ngay cả khi hàm đã kết thúc hoạt động của hàm. 1 /* Fig. 5.12: fig05_12.c 2 A scoping example */ 3 #include <stdio.h> 4 5 void useLocal( void ); /* function prototype */ 6 void useStaticLocal( void ); /* function prototype */ 7 void useGlobal( void ); /* function prototype */ 8 9 int x = 1; /* global variable */ 10 11 /* function main begins program execution */ 12 int main() 13 { 14 int x = 5; /* local variable to main */ 15 16 printf("local x in outer scope of main is %d\n", x ); 17 18 { /* start new scope */ 19 int x = 7; /* local variable to new scope */ 20 21 printf( "local x in inner scope of main is %d\n", x ); 22 } /* end new scope */ 23 24 printf( "local x in outer scope of main is %d\n", x ); 25 26 useLocal(); /* useLocal has automatic local x */ 27 useStaticLocal(); /* useStaticLocal has static local x */ 28 useGlobal(); /* useGlobal uses global x */ 29 useLocal(); /* useLocal reinitializes automatic local x */ 30 useStaticLocal(); /* static local x retains its prior value */ 31 useGlobal(); /* global x also retains its value */ 32 33 printf( "local x in main is %d\n", x ); 34 35 return 0; /* indicates successful termination */ 36 37 } /* end main */ 38 39 /* useLocal reinitializes local variable x during each call */ 40 void useLocal( void ) 41 { 42 int x = 25; /* initialized each time useLocal is called */ 43 44 printf( "\nlocal x in a is %d after entering a\n", x ); 45 x++; 46 printf( "local x in a is %d before exiting a\n", x ); 47 } /* end function useLocal */ 48 49 /* useStaticLocal initializes static local variable x only the first time 50 the function is called; value of x is saved between calls to this 51 function */ 52 void useStaticLocal( void ) 53 { 54 /* initialized only first time useStaticLocal is called */ 55 static int x = 50; 56 57 printf( "\nlocal static x is %d on entering b\n", x ); 58 x++; 59 printf( "local static x is %d on exiting b\n", x ); 60 } /* end function useStaticLocal */ 61 62 /* function useGlobal modifies global variable x during each call */ 63 void useGlobal( void ) 64 { 65 printf( "\nglobal x is %d on entering c\n", x ); 66 x *= 10; 67 printf( "global x is %d on exiting c\n", x ); 68 } /* end function useGlobal */ local x in outer scope of main is 5 local x in inner scope of main is 7 local x in outer scope of main is 5 local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 50 on entering b local static x is 51 on exiting b global x is 1 on entering c global x is 10 on exiting c local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 51 on entering b local static x is 52 on exiting b global x is 10 on entering c global x is 100 on exiting c local x in main is 5 13 Truy Truy ề ề n m n m ả ả ng ng cho cho h h à à m m  Để truyền mộtmảng cho hàm, chỉ ra tên củamảng, không sử dụng cặp “[]” int myArray[ 24 ]; myFunction( myArray, 24 ); – Kích thước của mảng cần được truyền qua hàm • Mảng được truyền thông qua lời gọi tham chiếu • Tên củamảng là địa chỉ phần tử đầu tiên • Hàm biết được nơi lưu trữ mảng – Thực hiện thay đổi tại vị trí chứa mảng trong bộ nhớ  Truyền các phần tử mảng • Truyền thông qua lời gọi bởi giá trị (truyền theo trị) • Truyền tên mảng cùng chỉ số tới hàm (ví dụ: myarray[3]) 14 Truy Truy ề ề n m n m ả ả ng cho h ng cho h à à m m  Khai báo nguyên mẫu hàm (function prototype) để truyền mảng cho hàm void modifyArray( int b[], int arraySize ); • Có thể bỏ qua tên mảng trong khai báo nguyên mẫu hàm – int b[] có thể được viếtint[] – int arraySize có thể được viết đơn giản là int • Tên của array chính là &array[ 0 ] (địa chỉ của phần tử đầu tiên trong mảng) do vậy khi truyền mảng (tham biến) thông qua gọi hàm không cần sử dụng dấu & Ví dụ gọi hàm với khai báo nguyên mẫu trên: int a[10], n = 10; modifyArray( a, n); // không sử dụng &a array = 0012FF78 &array[0] = 0012FF78 &array = 0012FF78 1 /* Fig. 6.12: fig06_12.c 2 The name of an array is the same as &array[ 0 ] */ 3 #include <stdio.h> 4 5 /* function main begins program execution */ 6 int main() 7 { 8 char array[ 5 ]; /* define an array of size 5 */ 9 10 printf( " array = %p\n&array[0] = %p\n" 11 " &array = %p\n", 12 array, &array[ 0 ], &array ); 13 14 return 0; /* indicates successful termination */ 15 16 } /* end main */ Ví dụ: Tên của array chính là &array[ 0 ] (địa chỉ của phần tử đầu tiên trong mảng) 1 /* Fig. 6.13: fig06_13.c 2 Passing arrays and individual array elements to functions */ 3 #include <stdio.h> 4 #define SIZE 5 5 6 /* function prototypes */ 7 void modifyArray( int b[], int size ); 8 void modifyElement( int e ); 9 10 /* function main begins program execution */ 11 int main() 12 { 13 int a[ SIZE ] = { 0, 1, 2, 3, 4 }; /* initialize a */ 14 int i; /* counter */ 15 16 printf( "Effects of passing entire array by reference:\n\nThe " 17 "values of the original array are:\n" ); 18 19 /* output original array */ 20 for ( i = 0; i < SIZE; i++ ) { 21 printf( "%3d", a[ i ] ); 22 } /* end for */ 23 24 printf( "\n" ); 25 Ví dụ: -Truyền mảng b và thay đổi các phần tử của mảng khi gọi hàm (tham chiếu) -Truyền phần tử của mảng qua hàm (tham trị) fig06_13.c (Part 2 of 3) fig06_13.c (Part 2 of 3) 26 /* pass array a to modifyArray by reference */ 27 modifyArray( a, SIZE ); 28 29 printf( "The values of the modified array are:\n" ); 30 31 /* output modified array */ 32 for ( i = 0; i < SIZE; i++ ) { 33 printf( "%3d", a[ i ] ); 34 } /* end for */ 35 36 /* output value of a[ 3 ] */ 37 printf( "\n\n\nEffects of passing array element " 38 "by value:\n\nThe value of a[3] is %d\n", a[ 3 ] ); 39 40 modifyElement( a[ 3 ] ); /* pass array element a[ 3 ] by value */ 41 42 /* output value of a[ 3 ] */ 43 printf( "The value of a[ 3 ] is %d\n", a[ 3 ] ); 44 45 return 0; /* indicates successful termination */ 46 47 } /* end main */ 48 49 /* in function modifyArray, "b" points to the original array "a" 50 in memory */ 51 void modifyArray( int b[], int size ) 52 { 53 int j; /* counter */ 54 55 /* multiply each array element by 2 */ 56 for ( j = 0; j < size; j++ ) { 57 b[ j ] *= 2; 58 } /* end for */ 59 60 } /* end function modifyArray */ 61 62 /* in function modifyElement, "e" is a local copy of array element 63 a[ 3 ] passed from main */ 64 void modifyElement( int e ) 65 { 66 /* multiply parameter by 2 */ 67 printf( "Value in modifyElement is %d\n", e *= 2 ); 68 } /* end function modifyElement */ -Mảng b sẽ thay đổi giá trị sau khi gọi thực hiện hàm modifyArray -Phần tử a[3] không thay đổi khi truyền cho biến e khi gọi hàm modifyElement Effects of passing entire array by reference: The values of the original array are: 0 1 2 3 4 The values of the modified array are: 0 2 4 6 8 Effects of passing array element by value: The value of a[3] is 6 Value in modifyElement is 12 The value of a[ 3 ] is 6 20 Truy Truy ề ề n tham s n tham s ố ố cho h cho h à à m m  Truyền tham trị  Truyền tham số trong hàm sử dụng con trỏ (truyền theo tham chiếu) • Sử dụng toán tử & để truyền địa chỉ của biến • Cho phép chúng ta thay đổi một vị trí thực sự trên bộ nhớ • Các array thì không sử dụng & bởi vì tên array là con trỏ  Sử dụng * để thay đổi giá trị của tham biến trong hàm void Intdouble( int *number ) { *number = 2 * ( *number ); } • Trong đó: *number sử dụng như tên biến (bí danh) 1 /* Fig. 7.6: fig07_06.c 2 Cube a variable using call-by-value */ 3 #include <stdio.h> 4 5 int cubeByValue( int n ); /* prototype */ 6 7 int main() 8 { 9 int number = 5; /* initialize number */ 10 11 printf( "The original value of number is %d", number ); 12 13 /* pass number by value to cubeByValue */ 14 number = cubeByValue( number ); 15 16 printf( "\nThe new value of number is %d\n", number ); 17 18 return 0; /* indicates successful termination */ 19 20 } /* end main */ 21 22 /* calculate and return cube of integer argument */ 23 int cubeByValue( int n ) 24 { 25 return n * n * n; /* cube local variable n and return result */ 26 27 } /* end function cubeByValue */ The original value of number is 5 The new value of number is 125 1 /* Fig. 7.7: fig07_07.c 2 Cube a variable using call-by-reference with a pointer argument */ 3 4 #include <stdio.h> 5 6 void cubeByReference( int *nPtr ); /* prototype */ 7 8 int main() 9 { 10 int number = 5; /* initialize number */ 11 12 printf( "The original value of number is %d", number ); 13 14 /* pass address of number to cubeByReference */ 15 cubeByReference( &number ); 16 17 printf( "\nThe new value of number is %d\n", number ); 18 19 return 0; /* indicates successful termination */ 20 21 } /* end main */ 22 23 /* calculate cube of *nPtr; modifies variable number in main */ 24 void cubeByReference( int *nPtr ) 25 { 26 *nPtr = *nPtr * *nPtr * *nPtr; /* cube *nPtr */ 27 } /* end function cubeByReference */ Gọi hàm và sử dụng truyền biến con trỏ Trong hàm cubeByReference, *nPtr đượcsử dụng (*nPtr là số nguyên). Truyền tham biếnsử dụng pointer, trỏ tớisố integer. The original value of number is 5 The new value of number is 125 23 Con tr Con tr ỏ ỏ l l à à m tham bi m tham bi ế ế n c n c ủ ủ a h a h à à m m 1 /* Fig. 7.10: fig07_10.c 2 Converting lowercase letters to uppercase letters 3 using a non-constant pointer to non-constant data */ 4 5 #include <stdio.h> 6 #include <ctype.h> 7 8 void convertToUppercase( char *sPtr ); /* prototype */ 9 10 int main() 11 { 12 char string[] = "characters and $32.98"; /* initialize char array */ 13 14 printf( "The string before conversion is: %s", string ); 15 convertToUppercase( string ); 16 printf( "\nThe string after conversion is: %s\n", string ); 17 18 return 0; /* indicates successful termination */ 19 20 } /* end main */ 21 22 /* convert string to uppercase letters */ 23 void convertToUppercase( char *sPtr ) 24 { 25 while ( *sPtr != '\0' ) { /* current character is not '\0' */ 26 27 if ( islower( *sPtr ) ) { /* if character is lowercase, */ 28 *sPtr = toupper( *sPtr ); /* convert to uppercase */ 29 } /* end if */ 30 31 ++sPtr; /* move sPtr to the next character */ 32 } /* end while */ 33 34 } /* end function convertToUppercase */ The string before conversion is: characters and $32.98 The string after conversion is: CHARACTERS AND $32.98 25 Tham bi Tham bi ế ế n const đ n const đ ố ố i v i v ớ ớ i h i h à à m trong C m trong C  const • biến không được phép thay đổi • Sử dụng const nếu hàm không cần thay đổi giá trị của biến • Cố tình thay đổi biến const sẽ gây lỗi  const pointers • Trỏ tới vùng nhớ cố định • Phải được khởi tạo khi định nghĩa • int *const myPtr = &x; – Kiểu int *const – con trỏ hằng trỏ đến vùng nhớ kiểu int • const int *myPtr = &x; – Con trỏ thông thường trỏ đến const int • const int *const Ptr = &x; – con trỏ const trỏ đến một vùng nhớ const int – x c óthể thay đổi, nhưng *Ptr thì không. 1 /* Fig. 7.11: fig07_11.c 2 Printing a string one character at a time using 3 a non-constant pointer to constant data */ 4 5 #include <stdio.h> 6 7 void printCharacters( const char *sPtr ); 8 9 int main() 10 { 11 /* initialize char array */ 12 char string[] = "print characters of a string"; 13 14 printf( "The string is:\n" ); 15 printCharacters( string ); 16 printf( "\n" ); 17 18 return 0; /* indicates successful termination */ 19 20 } /* end main */ 21 22 /* sPtr cannot modify the character to which it points, 23 i.e., sPtr is a "read-only" pointer */ 24 void printCharacters( const char *sPtr ) 25 { 26 /* loop through entire string */ 27 for ( ; *sPtr != '\0'; sPtr++ ) { /* no initialization */ 28 printf( "%c", *sPtr ); 29 } /* end for */ 30 31 } /* end function printCharacters */ The string is: print characters of a string 1 /* Fig. 7.12: fig07_12.c 2 Attempting to modify data through a 3 non-constant pointer to constant data. */ 4 #include <stdio.h> 5 6 void f( const int *xPtr ); /* prototype */ 7 8 int main() 9 { 10 int y; /* define y */ 11 12 f( &y ); /* f attempts illegal modification */ 13 14 return 0; /* indicates successful termination */ 15 16 } /* end main */ 17 18 /* xPtr cannot be used to modify the 19 value of the variable to which it points */ 20 void f( const int *xPtr ) 21 { 22 *xPtr = 100; /* error: cannot modify a const object */ 23 } /* end function f */ Ví dụ:trường hợp không được phép thay đổigiátrị khi sử dụng con trỏ hằng. 29 Con tr Con tr ỏ ỏ h h à à m m  Khai báo con trỏ hàm double (*f)(double): f là con trỏ hàm kiểu double, có một đối kiểu double double (*g)(double, int): g là con trỏ hàm kiểu double, có hai đối theo thứ tự là kiểu double và kiểu int double (*af[10])(double, int): af là mảng gồm 10 con trỏ hàm kiểu double, có hai đối theo thứ tự là kiểu double và kiểu int  Con trỏ hàm dùng để chứa địa chỉ của hàm 30 Cách dùng:  Gán tên hàm cho con trỏ hàm (kiểu hàm và kiểu con trỏ hàm phải tương thích). Sau phép gán có thể dùng tên con trỏ hàm thay cho tên hàm.  Đối con trỏ hàm: Khi sử dụng con trỏ hàm là tham biến của một hàm thì tham số thực sự tương ứng trong lời gọi hàm là tên của hàm cùng kiểu. 31  Ví dụ sử dụng con trỏ hàm làm tham biến của một hàm: Tính gần đúng tích phân xác định theo công thức hình thang.  Tính gần đúng tích phân theo công thức hình thang, với phép chia [a,b] thành n đoạn bằng nhau: • Lập bảng giá trị của hàm số y = f(x) • x i = x 0 + i.h, i = 0 n, x 0 = a; h = (b - a)/n; y i = f(x i ), i = 0 n. • I ≈ I T • I T = h.((y 0 +y n )/2 + y 1 + + y n-1 ) ∫ = b a dxxfI )( 32 #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <math.h> #include <alloc.h> double f(double x); double TP(double (*f)(double), float a, float b, int n); void main() { float a = 0, b = 1; int n = 10; clrscr(); printf("\nTich phan sin(x) tren [%.2f, %.2f] xap xi bang:\n\t %lf", a, b, TP(sin, a, b, n)); printf("\nTich phan f(x) = 1/(1 + x) tren [%.2f, %.2f] xap xi bang:\n\t%lf", a, b, TP(f, a, b, n)); getch(); } 33 double f(double x) { return (1/(1 + x)); } double TP(double (*f)(double), float a, float b, int n) { double h, *x, *y, IT; int i; x = (double*) malloc((n+1)*sizeof(double)); y = (double*) malloc((n+1)*sizeof(double)); h = (b - a)/n; for ( i = 0; i <= n; i++) { x[i] = a + i*h; y[i] = f(x[i]); printf("\n %lf\t%lf", x[i], y[i]); } for (i = 1, IT = (y[0] + y[n])/2; i < n; i++) { IT += y[i]; } return (IT*h); } 34 B B À À I T I T Ậ Ậ P P 1. Viết hàm giải hệ phương trình: {a.x + b.y = c; d.x + e.y = f} 2. Viết hàm giải hệ phương trình đại số tuyến tính Ax = b, A = (a ij ) NxN theo phương pháp Gauss 3. Viết hàm tìm gần đúng nghiệm của phương trình f(x) = 0 trên [a, b] bằng phương pháp chia đôi. Giả thiết f(x) liên tục, đơn điệu trên [a, b] và f(a).f(b) < 0. . 0 K K Ỹ Ỹ THU THU Ậ Ậ T L T L Ậ Ậ P TRÌNH P TRÌNH KỸ THUẬT PHÁT TRIỂN CHƯƠNG TRÌNH NỘI DUNG  Hàm và Thủ tục  Phát triển chương trình bằng phương pháp tinh chỉnh dần từng bước. . phương trình: {a.x + b.y = c; d.x + e.y = f} 2. Viết hàm giải hệ phương trình đại số tuyến tính Ax = b, A = (a ij ) NxN theo phương pháp Gauss 3. Viết hàm tìm gần đúng nghiệm của phương trình. khi dùng #include <stdio.h>, ta có thể gọi hàm scanf,…  Lời gọi hàm • Xuất phát từ chương trình chính (main) hoặc từ 1 hàm nào đó. • Yêu cầu gọi các hàm: – Cung cấp tên hàm và các đối số –

Ngày đăng: 02/08/2014, 15:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan