intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

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

Chia sẻ: Nguyễn Văn Cường | Ngày: | Loại File: PDF | Số trang:9

225
lượt xem
49
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

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 • 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 , 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 đó....

Chủ đề:
Lưu

Nội dung Text: KỸ THUẬT LẬP TRÌNH (p6)

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

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
2=>2