Bài giảng Lập trình cơ bản - Bài 9: Giới thiệu về hàm
Hàm
Hàm là một đoạn chương trình thực hiện một tác vụ được định nghĩa cụ thể
Các hàm được sử dụng để rút gọn cho một chuỗi các chỉ thị được thực hiện nhiều lần
Hàm dễ viết và dễ hiểu
Việc gỡ lỗi chương trình trở nên dễ dàng hơn khi cấu trúc của chương trình rõ ràng với hình thức lập trình theo module
Chương trình cấu tạo từ các hàm cũng dễ dàng bảo trì, bởi vì sự sửa đổi khi có yêu cầu được giới hạn trong từng hàm của chương trình
Cấu trúc hàm
Cú pháp tổng quát của một hàm trong C như sau:
type_specifier xác định kiểu dữ liệu của giá trị mà hàm sẽ trả về.
Một tên hàm hợp lệ được gán cho định danh của hàm
Các đối số xuất hiện trong cặp dấu ngoặc () được gọi là các tham số hình thức.
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình cơ bản - Bài 9: Giới thiệu về hàm", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
Tóm tắt nội dung tài liệu: Bài giảng Lập trình cơ bản - Bài 9: Giới thiệu về hàm
Bài 9: Giới thiệu về hàm
Bài giảng LẬP TRÌNH CƠ BẢN
KHOA CÔNG NGHỆ THÔNG TIN
BỘ MÔN CÔNG NGHỆ PHẦN MỀM
Tài liệu tham khảo
Giới thiệu về hàm
Kỹ thuật lập trình C: cơ sở và nâng cao, Phạm Văn Ất, Nhà xuất bản KHKT – Chương 6
The C programming language 2nd Edition, Brian Kernighan and Dennis Ritchie, Prentice Hall Software Series – Chương 4
2
Giới thiệu về hàm
Mục tiêu của bài học
Tìm hiểu cách sử dụng hàm
Tìm hiểu cấu trúc của hàm
Khai báo hàm và các nguyên mẫu hàm
Tìm hiểu các kiểu khác nhau của biến
Hàm được gọi như thế nào
Truyền bằng giá trị
Truyền bằng tham chiếu
Tìm hiểu về các qui tắc về phạm vi của hàm
Các hàm trong các chương trình có nhiều tập tin
Các lớp lưu trữ
Con trỏ hàm
3
Giới thiệu về hàm
Hàm
Hàm là một đoạn chương trình thực hiện một tác vụ được định nghĩa cụ thể
Các hàm được sử dụng để rút gọn cho một chuỗi các chỉ thị được thực hiện nhiều lần
Hàm dễ viết và dễ hiểu
Việc gỡ lỗi chương trình trở nên dễ dàng hơn khi cấu trúc của chương trình rõ ràng với hình thức lập trình theo module
Chương trình cấu tạo từ các hàm cũng dễ dàng bảo trì, bởi vì sự sửa đổi khi có yêu cầu được giới hạn trong từng hàm của chương trình
4
Giới thiệu về hàm
Cấu trúc hàm
Cú pháp tổng quát của một hàm trong C như sau:
type_specifier xác định kiểu dữ liệu của giá trị mà hàm sẽ trả về.
Một tên hàm hợp lệ được gán cho định danh của hàm
Các đối số xuất hiện trong cặp dấu ngoặc () được gọi là các tham số hình thức.
5
Giới thiệu về hàm
Các đối số của hàm
Chương trình tính bình phương của các số từ 1 đến 10
Dữ liệu được truyền từ hàm main() đến hàm squarer()
Hàm thao tác trên dữ liệu sử dụng các đối số
Actual Arguments
Formal Arguments
6
Giới thiệu về hàm
Sự trở về từ một hàm
Lệnh return ngay lập tức chuyển điều khiển từ hàm trở về chương trình gọi.
Giá trị đặt trong cặp dấu ngoặc () theo sau lệnh return được trả về cho chương trình gọi.
7
Giới thiệu về hàm
Kiểu dữ liệu của hàm
type_specifier không xuất hiện trước hàm squarer(), vì squarer() trả về một giá trị kiểu số nguyên int
type_specifier là không bắt buộc nếu kiểu của giá trị trả về là một số nguyên hoặc nếu không có giá trị trả về
Tuy nhiên, để tránh sự không nhất quán, một kiểu dữ liệu nên được xác định.
8
Giới thiệu về hàm
Gọi hàm
Dấu chấm phẩy được đặt cuối câu lệnh khi gọi hàm, nhưng không dùng cho định nghĩa hàm
Cặp dấu ngoặc () là bắt buộc theo sau tên hàm, cho dù hàm có đối số hay không
Nhiều nhất một giá trị được trả về
Chương trình có thể có nhiều hơn một hàm
Hàm gọi đến một hàm khác được gọi là hàm gọi
Hàm đang được gọi đến được gọi là hàm được gọi
9
Giới thiệu về hàm
Khai báo hàm
Việc khai báo hàm là bắt buộc khi hàm được sử dụng trước khi nó được định nghĩa
Hàm address() được gọi trước khi nó được định nghĩa
Một số trình biên dịch C sẽ thông báo lỗi nếu hàm không được khai báo trước khi gọi
Điều này còn được gọi là sự khai báo không tường minh
#include
address();
main(){
address()
}
address(){
}
10
Giới thiệu về hàm
Xác định kiểu dữ liệu của các đối số
Nguyên mẫu hàm
char abc(int x, nt y);
Thuận lợi :
Bất kỳ sự chuyển kiểu không hợp lệ giữa các đối số được dùng để gọi hàm và kiểu đã được định nghĩa cho các tham số của hàm sẽ được thông báo.
char noparam (void);
11
Giới thiệu về hàm
Biến cục bộ
Được khai báo bên trong một hàm
Được tạo tại điểm vào của một khối và bị hủy tại điểm ra khỏi khối đó
Tham số hình thức
Được khai báo trong định nghĩa hàm như là các tham số
Hoạt động như một biến cục bộ bên trong một hàm
Biến toàn cục
Được khai báo bên ngoài tất cả các hàm
Lưu các giá trị tồn tại suốt thời gian thực thi của chương trình
Các biến
12
Giới thiệu về hàm
Lớp lưu trữ
Mỗi biến trong C có một tính chất được gọi là lớp lưu trữ
Lớp lưu trữ định nghĩa hai đặc tính của biến:
Thời gian sống của một biến là khoảng thời gian nó duy trì một giá trị xác định
Tầm vực của một biến xác định các phần của một chương trình có thể nhận ra biến đó
13
Giới thiệu về hàm
auto
extern
static
register
Lớp lưu trữ - tt
14
Giới thiệu về hàm
Các qui luật phạm vi – là những qui luật quyết định một đoạn mã lệnh có thể truy xuất đến một đoạn mã lệnh hay dữ liệu khác hay không
Mã lệnh bên trong một hàm là cục bộ với hàm đó
Hai hàm có cùng mức phạm vi
Một hàm không thể được định nghĩa bên trong một hàm khác
Các qui luật phạm vi của hàm
15
Giới thiệu về hàm
Gọi hàm
Truyền tham trị
Truyền tham chiếu
16
Giới thiệu về hàm
Truyền bằng giá trị
Mặc nhiên trong C, tất cả các đối số được truyền bằng giá trị
Khi các đối số được truyền đến hàm được gọi, các giá trị được truyền thông qua các biến tạm
Mọi sự thao tác chỉ được thực hiện trên các biến tạm
Các đối số được gọi là truyền bằng giá trị khi giá trị của biến được truyền đến hàm được gọi và bất kỳ sự thay đổi trên giá trị này không ảnh hưởng đến giá trị gốc của biến được truyền
17
Giới thiệu về hàm
Truyền bằng tham chiếu
Với truyền tham chiếu, hàm cho phép truy xuất đến địa chỉ thực trong bộ nhớ của đối số và vì vậy có thể thay đổi giá trị của các đối số của hàm gọi
Định nghĩa
getstr(char *ptr_str, int *ptr_int);
Gọi
getstr(pstr, &var);
18
Giới thiệu về hàm
Khi mảng được truyền vào hàm như một đối số, chỉ có địa chỉ của mảng được truyền.
Tên mảng chính là là địa chỉ của mảng.
void main() {
int ary[10];
fn_ary(ary);
}
Truyền Mảng vào Hàm
19
Giới thiệu về hàm
Truyền Mảng vào Hàm - tt
#include
int sum_arr(int num_arr[]);
/* Khai báo hàm */
void main() {
int num[5], ctr, sum=0;
clrscr();
for(ctr=0;ctr<5;ctr++) {
/*Nhập các phần tử của mảng */
printf("\nEnter number %d:",ctr+1);
scanf("%d", &num[ctr]);
}
20
Giới thiệu về hàm
sum=sum_arr(num);/*Gọi hàm*/
printf("\nThe sum of the array is %d",sum);
getch();
}
int sum_arr(int num_arr[]){
/*ĐỊnh nghĩa hàm*/
int i, total;
for(i=0,total=0;i<5;i++)
/* Calculates the sum */
total+=num_arr[i];
return total;
/* Trả lại giá trị sum cho main() */
}
Truyền Mảng vào Hàm -tt
21
Giới thiệu về hàm
Kết quả của chương trình trên:
Enter number 1: 5
Enter number 2: 10
Enter number 3: 13
Enter number 4: 26
Enter number 5: 21
The sum of the array is 75
Truyền Mảng vào Hàm - tt
22
Giới thiệu về hàm
Ví dụ Truyền Mảng vào Hàm
#include
#include
int longest(char lines_arr[][20]);
/* Khai báo hàm */
void main() {
char lines[5][20];
int ctr, longctr=0;
clrscr();
for(ctr=0;ctr<5;ctr++) {
/*Nhập các xâu kí tự vào mảng*/
printf("\nEnter string %d:",ctr+1);
scanf("%s", lines[ctr]);
}
23
Giới thiệu về hàm
longctr=longest(lines);
/*Truyền mảng cho hàm*/
printf("\n The longest string is %s", lines[longctr]);
getch();
}
int longest(char lines_arr[][20]) {
/*Định nghĩa hàm*/
int i=0, l_ctr=0, prev_len, new_len;
prev_len=strlen(lines_arr[i]);
/*Xác định độ dài xâu đầu tiên*/
Vd Truyền Mảng vào Hàm - tt
24
Giới thiệu về hàm
for(i++;i<5;i++) {
new_len=strlen(lines_arr[i]);
/* Xác định độ dài các thành phần tiếp theo */
if(new_len > prev_len)
{l_ctr=i;
/* Lưu lại giá trị lớn hơn */
prev_len=new_len;
}
}
return l_ctr;
/* Returns the subscript of the longest string */
}
Vd Truyền Mảng vào Hàm - tt
25
Giới thiệu về hàm
Kết quả của chương trình trên:
Enter string 1: The
Enter string 2: Sigma
Enter string 3: Protocol
Enter string 4: Rober
Enter string 5: Ludlum
The longest string is
Vd Truyền Mảng vào Hàm - tt
26
Giới thiệu về hàm
27
Giới thiệu về hàm
Sự lồng nhau của lời gọi hàm
main()
{
palindrome();
}
palindrome()
{
getstr();
reverse();
cmp();
}
28
Giới thiệu về hàm
Các hàm trong chương trình
có nhiều tập tin
Các hàm cũng có thể được định nghĩa là static hoặc external
Các hàm tĩnh (static) chỉ được nhận biết bên trong tập tin chương trình và phạm vi của nó không vượt ra khỏi tập tin chương trình
static fn _type fn_name (argument list);
Hàm ngoại (external) được nhận biết bởi tất cả các tập tin của chương trình
extern fn_type fn_name (argument list);
29
Giới thiệu về hàm
Con trỏ hàm
Lưu địa chỉ bắt đầu của hàm
Hàm có một vị trí vật lý trong bộ nhớ, vị trí này có thể gán cho một con trỏ
void check(char *a, char *b, int (*cmp)())
{
printf(“testing for equality \n”);
if (!(*cmp)(a,b))
printf(“Equal”);
else
printf(“Not Equal”);
}
#include
#include
void check(char *a, char *b, int (*cmp)());
main() {
char sl[80];
int (*p)();
p = strcmp;
gets(s1);
gets(s2);
check(s1, s2, p);
}
30
Hàm inline
Giới thiệu về hàm
31
đầu dòng khai báo và định nghĩa hàm
inline int max(int a, int b) {
return (a > b)? a : b;
}
Hàm inline khác biệt hàm thông thường:
"Hàm inline" thực chất không phải là một hàm!
Khi gọi hàm thì lời gọi hàm được thay thế một cách thông minh bởi mã nguồn định nghĩa hàm, không thực hiện các thủ tục gọi hàm
Giới thiệu về hàm
32
Ví dụ:
l=max(k*5-2,l);
Được thay thế bằng các dòng lệnh kiểu như:
int x=k*5-2; // biến tạm trung gian
l=(x>l)?x:l; // OK
Khi nào dùng hàm inline
Giới thiệu về hàm
33
Ưu điểm của hàm inline:
Tiện dụng như hàm bình thường
Hiệu suất như viết thẳng mã, không gọi hàm
Tin cậy, an toàn hơn nhiều so với sử dụng Macro
Nhược điểm của hàm inline:
Nếu gọi hàm nhiều lần trong chương trình, mã chương trình có thể lớn lên nhiều (mã thực hiện hàm xuất hiện nhiều lầntrong chương trình)
Mã định nghĩa hàm phải để mở => đưa trong header file
Lựa chọn xây dựng và sử dụng hàm inline khi:
Mã định nghĩa hàm nhỏ (một vài dòng lệnh, không chứa vòng lặp)
Yêu cầu về tốc độ đặt ra trước dung lượng bộ nhớ
Đệ quy
Giới thiệu về hàm
34
Một hàm được gọi là đệ quy nếu bên trong thân hàm có lệnh gọi đến chính nó.
Ví dụ: Người ta định nghĩa giai thừa của một số nguyên dương n như sau:
n!=1* 2 * 3 ** (n-1) *n = (n-1)! *n (với 0!=1)
Như vậy, để tính n! ta thấy nếu n=0 thì n!=1 ngược lại thì n!=n * (n-1)!
Giới thiệu về hàm
35
Hàm đệ quy phải có 2 phần:
Phần dừng hay phải có trường hợp nguyên tố. Trong ví dụ ở trên thì trường hợp n=0 là trường hợp nguyên tố.
Phần đệ quy: là phần có gọi lại hàm đang được định nghĩa. Trong ví dụ trên thì phần đệ quy là n>0 thì n! = n * (n-1)!
Sử dụng hàm đệ quy trong chương trình sẽ làm chương trình dễ đọc, dễ hiểu và vấn đề được nêu bật rõ ràng hơn.
Đa số trường hợp thì hàm đệ quy tốn bộ nhớ nhiều hơn và tốc độ thực hiện chương trình chậm hơn không đệ quy.
Tùy từng bài có cụ thể mà người lập trình quyết định có nên dùng đệ quy hay không.
Tóm tắt nội dung
Giới thiệu về hàm
36
Prototype, định nghĩa và các kiểu của hàm
Biến cục bộ
Truyền tham số và giá trị trả lại
Tham trị
Tham chiếu
Hàm inline, đặc điểm của hàm inline
Đệ quy với lời gọi đến chính nó
Thảo luận
Giới thiệu về hàm
37
Khi nào dùng tham chiếu, khi nào dùng tham trị
Chuyển đệ quy về dạng lặp
CÂU HỎI VÀ BÀI TẬP
Giới thiệu về hàm
38
Bài 22: Viết hàm tính ước số chung lớn nhất của 2 số tự nhiên a, b.
Bài 23: Viết hàm xác định một số tự nhiên có phải nguyên tố hay không.
Bài 24: Viết hàm nhập mảng, in mảng, hàm sắp xếp mảng bằng phương pháp chia đôi; hàm main sử dụng các hàm trên.
Bài 25: Viết hàm nhập ma trận, in ma trận, hàm nhân 2 ma trận, hàm kiểm tra ma trận đơn vị; hàm main sử dụng các hàm trên để nhập và kiểm tra 2 ma trận có là nghịch đảo của nhau hay không.
HỎI VÀ ĐÁP
Máy tính điện tử và xử lý thông tin
File đính kèm:
bai_giang_lap_trinh_co_ban_bai_9_gioi_thieu_ve_ham.ppt

