bài giảng cấu trúc điều khiểncác cấu trúc điều khiển trong ngôn ngữ ccác cấu trúc điều khiển trong ccác cấu trúc điều khiển trong pascalgiao trinh turbo pascal 7 0 fullgiao trinh turbo pascal 7 0 full
Trang 1Chương 4: HÀM TỰ TẠO
Giáo viên: Tạ Thúc Nhu Khoa CNTT trường ĐH Lạc Hồng
NGÔN NGỮ C
Trang 2Nội dung
Nội dung
I Tổng Quan
II Định nghĩa hàm tự tạo
III Phân loại tham số hình thức
IV Tính Đệ qui của hàm
Trang 3I- Tổng Quan:
I- Tổng Quan:
• C cung cấp rất nhiều hàm, các hàm này được lưu trong các
thư viện mà khi sử dụng ta cần phải khai báo bằng phát
biểu #include
• Ngoài ra, C còn cho phép ta tạo thêm những hàm khác,
phục vụ mục đích riêng nào đó Các hàm này có thể được
viết chung bên trong file chương trình hoặc viết trong một
tập tin khác và có thể nạp vào chương trình bằng phát biểu
#include như các file thư viện của C.
• Nhờ vào khả năng này mà một chương trinh lớn có thể
được viết bởi nhiều người Mỗi người phụ trách xây dựng
các hàm cho các chức năng được phân công
Trang 4II- Định nghĩa và sử dụng Hàm tự tạo:
1 Định nghĩa Hàm tự tạo
2 Gọi thực hiện hàm tự tạo:
Trang 5• TênHàm : phải khác nhau trong cùng 1 chương trình
• KiểuHàm : là kiểu của <biểu thức> trong lệnh return Nếu hàm không có
lệnh return hoăc có lệnh return; không có biểu thức thì dùng kiểu void.
• Lệnh return [biểu thức]; Dùng để thoát khỏi hàm, trở về nơi gọi hàm và
thay lời gọi hàm bằng giá trị của <biểu thức> (nếu có)
• Tham số (Parameter): là dữ liệu cần thiết cho việc xử lý của hàm.
• Tham số hình thức: là biến cục bộ đại diện cho tham số, dữ liệu của
tham số hình thức sẽ được cung cấp trong lời gọi hàm Các biến tham
số hình thức này chỉ được sử dụng bên trong thân hàm
Trang 6Ví dụ: Định nghĩa hàm tự tạo
Ví dụ: Định nghĩa hàm tự tạo
Ví dụ : Định nghĩa Hàm tính Giai thừa của một số tự nhiên N
long GiaiThua( int N )
• Tên biến trong và tham số hình thức phải khác nhau vì có
cùng phạm vi sử dụng là trong thân hàm Nhưng có thể
trùng tên với các biến bên ngoài hàm.
• Thân hàm : là một khối lệnh { và kết thúc bằng dấu }.
Trang 72- Gọi thực hiện hàm tự tạo:
2- Gọi thực hiện hàm tự tạo:
• Hàm có thể được gọi thực hiện trong các biểu thức hoặc có thể thực
hiện như một lệnh độc lập.
Cú pháp gọi hàm : tênhàm([danh sách tham số thực sự])
Ví dụ: Viết chương trình nhập vào 3 số nguyên và in ra màn hình số lớn trong 3 số
Trang 83- Nguyên tắc hoạt động của hàm
3- Nguyên tắc hoạt động của hàm
• Hàm đã định nghĩa không tự động thực hiện trừ khi ta có
một lời gọi đến hàm đó
Quá trình diễn ra khi gặp lời gọi hàm như sau:
• Nếu hàm có tham số, trước tiên các tham số sẽ được gán giá trị thực tương ứng
• Sau đó thực hiện tiếp các câu lệnh trong thân hàm bắt đầu từ lệnh đầu tiên
• Khi gặp lệnh return hoặc dấu } cuối cùng trong thân hàm,
chương trình sẽ thoát khỏi hàm để trở về chương trình đã
gọi hàm và thực hiện tiếp tục những câu lệnh của chương
trình này
Trang 94- Cấu trúc chương trình có hàm tự tạo :
4- Cấu trúc chương trình có hàm tự tạo :
• Các #include : dùng nạp header file chứa các hàm thư viện sử dụng trong chương trình:
• Các #define : dùng định nghĩa một tên đại diện cho một giá trị hay biểu
thức.
• Khai báo các đối tượng dữ liệu ngoài (biến, mảng, cấu trúc )
• Khai báo đặc trưng của các hàm tự tạo
Cú pháp: Kiểuhàm TênHàm( [Danh sách kiểu của các tham số hình thức] );
• Phần định nghiã các hàm tự tạo
• Hàm main()
Chú ý: Nếu không khai báo đăc trưng của hàm tự tạo thì vị trí định nghĩa các hàm trong chương trình như sau: Nếu trong thân hàm B có lời gọi thực
hiện hàm A thì phần định nghĩa hàm A phải trên phần định nghĩa hàm B.
Ví dụ : Viết chương trình tính số tổ hợp chập k của n :
C k
n = n!/(k!.(n - k)!)
Trang 10/*Khai bao dac trung cac ham */
long GiaiThua( int );
longToHop( int , int );
Trang 11III- Cách truyền tham số:
III- Cách truyền tham số:
• Việc khai báo các tham số hình thức cho hàm nhằm mục
đích tính toán, thao tác trên nhiều giá trị khác nhau
Ví dụ: Hàm long giaithua(int n): dùng tính giai thừa cho các số
tự nhiên khác nhau.
• Các tham số hình thức sẽ nhận các dữ liệu từ các tham số
thật sự trong lời gọi hàm
• Có 3 cách truyền dữ liệu cho tham số hình thức của hàm:
1 Truyền giá trị cho tham số hình thức
2 Truyền địa chỉ biến cho tham số hình thức
3 Truyền tên biến cho tham số hình thức
Trang 121- Truyền giá trị cho tham số hình thức
1- Truyền giá trị cho tham số hình thức
• Tham số thực sự là một biểu thức tùy ý
• Giá trị của biểu thức được truyền cho tham số hình thức.
• Tham số hình thức phải là biến cùng kiểu với giá trị biểu
thức để nhận giá trị của tham số thực sự
Trang 13Ví dụ: Tìm bội chung nhỏ nhất 2 số nguyên
Ví dụ: Tìm bội chung nhỏ nhất 2 số nguyên
Trang 142- Truyền địa chỉ biến:
2- Truyền địa chỉ biến:
• Tham số thực sự trong lời gọi hàm là địa chỉ một biến
• Tham số hình thức phải là biến chứa địa chỉ của biến truyền
• Biến chứa địa chỉ của biến khác được gọi là Biến con trỏ
(Pointer Variable).
• Cú pháp khai báo biến con trỏ: <Kiểu> * biếncontrỏ
• <Kiểu> của biến con trỏ phải cùng kiểu với biến truyền
• Đối với hàm, Biến truyền có tên thứ 2 là: ( * biếncontrỏ )
Trang 15Ví dụ: Giản ước phân số
Ví dụ: Giản ước phân số
void nhapphanso( int *x , int *y )
{ do{ printf("\nNhap tu va mau : ");
scanf("%d %d", x , y );
} while( *y != 0 );
if ( *y < 0) { *x = - ( *x );
printf(“Nhap phan so: \n “);
nhapphanso( &a , &b );
toigianps( &a , &b );
printf(“\nKet qua: %d/%d”,a,b);
int ucln(int m, int n);
void toigianps( int * , int * );
void nhapphanso( int * , int * );
int ucln(int m, int n)
void toigianps( int *tu , int *mau )
{ int usc = ucln( *tu , *mau );
*tu = *tu / usc;
*mau = *mau / usc;
Trang 163- Truyền tên biến cho tham số hình thức:
3- Truyền tên biến cho tham số hình thức:
• Tham số thực sự trong lời gọi hàm là tên biến truyền
• Tham số hình thức tương ứng là một bí danh (hay còn gọi
Tham chiếu ) của biến được truyền
• Cú pháp khai báo tham chiếu: Kiểu &Thamchieu
• <Kiểu> của tham chiếu phải cùng kiểu với biến truyền
Trang 17Ví dụ: Giản ước phân số bằng tham chiếu
Ví dụ: Giản ước phân số bằng tham chiếu
void nhapphanso( int &x , int &y )
{ do{ printf("\nNhap tu va mau : ");
scanf("%d %d", &x , &y );
} while( y != 0 );
if ( y < 0) { x = - x ;
y = - y ; }
printf(“\nKet qua: %d/%d”,a,b);
int ucln(int m, int n);
void toigianps( int & , int & );
void nhapphanso( int & , int & );
int ucln(int m, int n)
void toigianps( int &tu , int &mau )
{ int usc = ucln( tu , mau );
tu = tu / usc;
mau = mau / usc;
Trang 18Bài tập: Hàm tự tạo
Bài tập: Hàm tự tạo
1 Viết chương trình xác định BSCNN của 2 số tự nhiên M, N
theo công thức BSCNN(M,N)= M*N/UCLN(M,N) Trong đó,
xây dựng hàm:
• Tìm UCLN của 2 số nguyên: int UCLN( int M, int N);
• Tìm BCNN của 2 số nguyên: int BCNN( int M, int N);
2 Viết chương trình in ra các số nguyên tố nhỏ hơn hay bằng
n, với n là số nguyên lớn hơn 1 được nhập từ bàn phím
Yêu cầu xây dựng hàm kiểm tra 1 số có là số nguyên tố hay không, hàm này trả về số 0 nếu không là số nguyên tố:
int LaSoNguyenTo( int a);
Trang 19Bài tập: Hàm tự tạo
Bài tập: Hàm tự tạo
3 Viết chương trình vẽ ra màn hình tam giác Pascal chứa các hệ số khi khai triển
nhị thức: (a+b) n = C(0, n)a n + C(1, n)a n-1 b + C(2, n)a n-2 b 2 + + C(n,n)b n
Với chiều cao H (2<= H <= 10) nhập vào từ bàn phím
Hướng dẫn:Đoạn trình In tam giác Pascal cân với chiều cao H đã nhập
for (n=0; n < H; n++)
{ /*In các dấu cách: trung điểm cạnh đáy - nửa cạnh đáy hiện tại ứng với n */
for (i = 1, i < (H - n)*2; i++) printf(“ ”);
/*In các giá trị tổ hợp */
for (k = 0; k <= n; k++) printf(“%4ld”, C(k, n));
printf(“\n”);
Trang 20Bài tập: Hàm tự tạo
Bài tập: Hàm tự tạo
5 Viết chương trình tính Tổng, Hiệu, Tích, Thương của 2
phân số In kết quả dưới dạng phân số tối giản
Yêu cầu xây dựng các hàm:
• void CongPS(int t1, int m1, int t2, int m2, int &t3, int &m3);
• void TruPS(int t1, int m1, int t2, int m2, int &t3, int &m3);
• void NhanPS(int t1, int m1, int t2, int m2, int &t3, int &m3);
• int ChiaPS(int t1, int m1, int t2, int m2, int &t3, int &m3);
• int UCLN( int m, int n);
• void GianUocPS( int &m, int &n);
Trang 21IV- HÀM ĐỆ QUI : (Recurve Function)
IV- HÀM ĐỆ QUI : (Recurve Function)
1 Khái niệm : Hàm P được định nghĩa theo kiểu đệ qui, nếu
trong thân hàm P có lời gọi thực hiện đến chính hàm P.
Ví dụ: Theo định nghiã phép toán giai thừa
(a) 0! = 1! = 1 (b) n! = n * (n-1)! nếu n > 1
Ta có thể định nghĩa hàm tính giai thừa theo kiểu đệ qui:
long GiaiThua(int n)
{
if (n <= 1) return 1; //thành phần dừng return n * GiaiThua (n-1); //thành phần đề qui }
Trang 22IV- Hàm đệ qui (tt)
IV- Hàm đệ qui (tt)
2 Hàm đệ qui phải có 2 thành phần:
tham số tiến dần về điều kiện để thực hiện thành phần dừng.
Ví dụ: Tìm UCLN của 2 số nguyên không âm phương pháp Euclide :
(a) UCLN(x, y) = x nếu y = 0 (b) UCLN(x,y) = UCLN(y, phần dư của x/y) nếu y <> 0
Ta có thể định nghĩa hàm tìm UCLN theo kiểu đệ qui như sau:
int UCLN(int x, int y)
{
if (y == 0) return x;
return (ucln(y, x % y));
}
Trang 23Bài tập đệ qui
Bài tập đệ qui
1 Xây dựng hàm tính tổng các số nguyên từ 1 đến N, với N
>= 0.
2 Xây dựng hàm tính tổng N các số nguyên lẻ đầu tiên.
3 Tìm UCLN của 2 số nguyên không âm theo công thức sau :
(a) UCLN(x, y) = x nếu y = 0 (b) UCLN(x,y) = UCLN(x, y-x) nếu y >=x (c) UCLN(x,y) = UCLN(x - y, y) nếu x > y
4 Dãy số Fibonacci được định nghĩa như sau:
– F0 =1; F1=1;
– Fn=Fn-2+Fn-1 với n>=2
Xây dựng hàm đệ qui xác định giá trị phần tử thứ N >=0.
Trang 24Ví dụ : Bài toán Tháp Hà Nội (Tower of HaNoi)
Ví dụ : Bài toán Tháp Hà Nội (Tower of HaNoi)
Có 3 cột A, B, C và N điã kích thước phân biệt chồng ở cột A,
điã lớn ở dưới, điã nhỏ ở trên Hãy In ra các bước chuyển
các điã từ A sang C sao cho :
1 Mỗi lần chỉ được chuyển 1 điã
2 Cho phép dùng cột B để chứa tạm các đĩa.
3 Ở các cột luôn luôn là điã lớn ở dưới, điã nhỏ ở trên.
Chúng ta giải bài toán theo kiểu giải quyết từ trên xuống (Top
Down) như sau:
Để chuyển n điã từ A -> C: làm cách nào đó ta chuyển n-1 điã
từ A >B, sau đó chuyển điã lớn nhất còn lại từ A -> C Và rồi lại làm cách nào đó chuyển n-1 điã từ B > C
Trang 25Nếu n > 0
1 chuyển n-1 điã từ A sang B, lấy C làm trung gian
2 In thông báo chuyển 1 điã từ A sang C
3 chuyển n-1 điã từ B sang C, lấy A làm trung gian
Kết thúc
Trang 26void main() {
int SoDia;
printf(“Nhap so đia: “);
scanf(“%d”, &SoDia);
ChuyenDia(SoDia,’A’,’B,’C’); getch();