Lợi ích của việc dùng hàm
Phân biệt giữa hàm do người sử dụng
định nghĩa và các hàm chuẩn
Phân biệt giữa truyền tham trị và truyền
tham chiếu
Cách viết một hàm
Hàm và con trỏ
Bài tập minh họa
Hàm
Giúp phân chia một chương trình thành các
module nhỏ hơn
Mỗi module là 1 đoạn chương trình độc lập thực
hiện trọn vẹn một công việc nhất định, rồi trả về
một giá trị cho chương trình gọi nó
Hàm main() là thành phần bắt buộc, chương trình
thực hiện từ câu lệnh đầu tiên của hàm main()
đến khi gặp dấu } cuối cùng
Các module được kết hợp lại trong chương trình
chính
Không cho phép xây dựng một hàm bên trong
hàm khác
43 trang |
Chia sẻ: candy98 | Lượt xem: 779 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Bài giảng Cơ sở kỹ thuật lập trình - Chương 5: Hàm và cấu trúc chương trình - Trương Vĩnh Trường Duy, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Chương 5: Hàm và cấu
trúc chương trình
Biên soạn: Trương Vĩnh Trường Duy
(duytvt@ptithcm.edu.vn)
Từ tài liệu trên Internet và các nguồn khác
CƠ SỞ KỸ THUẬT LẬP TRÌNH
Nội dung
Lợi ích của việc dùng hàm
Phân biệt giữa hàm do người sử dụng
định nghĩa và các hàm chuẩn
Phân biệt giữa truyền tham trị và truyền
tham chiếu
Cách viết một hàm
Hàm và con trỏ
Bài tập minh họa
Hàm
Giúp phân chia một chương trình thành các
module nhỏ hơn
Mỗi module là 1 đoạn chương trình độc lập thực
hiện trọn vẹn một công việc nhất định, rồi trả về
một giá trị cho chương trình gọi nó
Hàm main() là thành phần bắt buộc, chương trình
thực hiện từ câu lệnh đầu tiên của hàm main()
đến khi gặp dấu } cuối cùng
Các module được kết hợp lại trong chương trình
chính
Không cho phép xây dựng một hàm bên trong
hàm khác
Bố cục chương trình C
Một chương trình C được tổ chức theo
mẫu:
Hàm 1
Hàm 2
Hàm n
Ở các vị trí bên ngoài hàm (), ta có thể
đặt các toán tử #include, #define, định
nghĩa kiểu dữ liệu, khai báo biến ngoài,
biến tĩnh ngoài
Hàm (ví dụ)
Chương trình nhận các chi tiết của 1 nhân viên để tính lương
Gồm các trường:
• Employee number
• Employee name
• Grade
• Basic Salary
• Standard allowance
• Standard deductions
Các chi tiết trong bảng lương:
• Employee number
• Employee name
• Grade
• Basic Salary
• Allowances
• Net salary
• Deductions
Hàm (ví dụ tiếp theo)
Cần thực hiện các tính toán sau:
Net salary = (Basic + Allowances) - Deductions
Allowances = House Rental Allowance(HRA) +
Standard allowance
Deduction = Standard deductions + Provident Fund
Provident fund is deducted at the rate of 6% of the
Basic salary
HRA and the allowance are based on the grade
Grade HRA
• 1 18% of Basic salary
• 2 15% of Basic salary
• 3 Nil
Hàm (ví dụ tiếp theo)
Trong bài toán trên, nếu viết mọi thứ trong
một module thì chương trình sẽ quá phức
tạp
Chương trình này sẽ được phân thành 2
chương trình nhỏ hơn có tên là:
Provident Fund Calculation
HRA Calculation
Hàm (ví dụ tiếp theo)
Đối với việc tính lương của 1 nhân viên:
Start
emp_no=0
Array emp_name[15] is a character
grade=0
basic=0
std_allow=0
std_ded=0
net_sal=0
allow=0
deduct=0
HRA=0
PF=0
reply = ‘y’
(to be continued...)
Hàm (ví dụ tiếp theo)
while reply=’y’
do
Accept emp_no, emp_name, grade, basic, std_all, std_ded
PF = PF_CAL()
HRA = HRA_CAL()
allow = HRA + std_allow
deduct = std_ded + PF
net_sal = (basic + allow) - deduct
display emp_no, emp_name, grade, basic, allow, deduct,
net_sal
display “Do you wish to continue(y/n)?”
Accept reply
enddo
End
Hàm (ví dụ tiếp theo)
Các hàm PF_CAL() và HRA_CAL()
PF_CAL ()
Start
if ( grade 3 )
PF = .06 * basic
else
PF = 0
endif
Return PF
HRA_CAL ()
Start
if ( grade = 1 )
HRA = .18 * basic
else
if ( grade = 2 )
HRA = .15 * basic
else
HRA = 0
endif
endif
Return HRA
Ưu điểm của việc dùng hàm
Dễ bảo trì code
Giúp code dễ đọc, dễ hiểu
Loại trừ những đoạn mã dư thừa
Cho phép tái sử dụng code
Chương trình tính x^3
Tham số của hàm
Hàm cộng hai giá trị và hiển thị tổng:
Start
Add(2, 5)
End
Add(x is an integer, y is an integer)
Start
Declare sum as an integer
sum = x + y
Display sum
return
Hàm Add(x is an integer, y is an integer) nhận 2 tham số
nguyên x và y
Hàm Add(2, 5) được gọi với các trị truyền vào là 2 và 5
Tham số của hàm(tiếp theo)
Cần bảo đảm truyền đúng trật tự và số lượng các tham số:
Ví dụ:
Start
Declare num as an integer
num = 10
Add(2, 5)
Add(‘9’, 4, 6)
Add(2, 5, num)
End
Add(x is integer, y is integer, z is integer)
Start
sum is an integer
sum = x + y + z
Display sum
return
Errors
Tham số của hàm(tiếp theo)
Kết quả hàm Add(2, 5) sẽ bị báo lỗi vì hàm
Add() được khai báo với 3 tham số nhưng
hàm gọi chỉ được truyền có 2 giá trị
Kết quả hàm Add(‘9’, 4, 6) cũng sẽ bị lỗi vì
‘9’ là 1 ký tự
Hàm Add(2, 5, num)
Giá trị trả về
Là giá trị của hàm được trả về cho
chương trình gọi (chương trình chính)
Mỗi hàm chỉ có thể trả về một trị cho
chương trình gọi nó
Giá trị trả về (ví dụ)
Tìm tổng của 2 số và trả về số tổng đó cho
chương trình chính
Start
sum is an integer
sum = Add(2,5)
Display sum
End
Add(x is an integer, y is an integer) returns integer
Start
var1 is an integer
var1 = x + y
return var1
Hàm
Hàm do người sử dụng định nghĩa
Được viết bởi người lập trình, tùy vào yêu
cầu của chương trình
Các Hàm chuẩn
Được đóng gói kèm theo công cụ lập trình
Thực hiện các thao tác thông dụng
Ví dụ:
• MsgBox(“thông báo”) trong MS Access
• MsgBox(“thông báo”) trong Visual Basic
Thư viện hàm
Tập hợp các hàm
Chứa các hàm liên quan đến một lĩnh vực trong
lập trình. Ví dụ, thư viện Math chứa các hàm tính
toán như: khai căn, lũy thừa, tính trung bình .
Mỗi khi kết hợp vào ứng dụng, chỉ cần gọi tên
hàm mà không cần viết lại các câu lệnh của nó.
Hàm được gọi trực tiếp với đúng kiểu và số
lượng tham số
Các hàm thường sử dụng thì được đặt trong thư
viện hàm
Cách viết một hàm
Xác định mục đích hàm: trước hết phải
xác định mục đích của hàm dùng để làm gì,
trên cơ sở đó ta xác định các thành phần
của hàm
Xác định các thành phần của hàm:
Nguyên mẫu của hàm
;
Ta có thể không ghi nguyên mẫu của hàm,
tuy nhiên nên nhóm các nguyên mẫu hàm
đặt trước hàm main() để dễ kiểm soát
Cách viết một hàm
Xác định các thành phần của hàm:
Kiểu giá trị của hàm: giá trị trả về của hàm
phải được xác định dựa vào mục đích của
hàm và trong thân hàm ta phải trả về đúng
kiểu giá trị đã định ban đầu
Tên hàm: đặt theo quy định đối với danh
định, nên ngắn gọn và phản ánh mục đích.
Tên hàm trong nguyên mẫu và khai báo
phải giống nhau
Tham số của hàm:
• Phân loại theo cách sử dụng
• Phân loại theo công dụng
Phân loại theo cách sử dụng
Tham số hình thức: các tham số ghi trong
nguyên mẫu hay ghi lúc khai báo hàm
Tham số thực: các giá trị, biến ghi sau tên
hàm khi gọi hàm đó để thực hiện
Tham chiếu: được truyền cho hàm dưới
dạng con trỏ (địa chỉ). Tham chiếu mới ghi
nhận lại được những kết quả tính toán khi
hàm kết thúc
Tham trị: được truyền cho hàm dưới dạng
biến, không bảo lưu lại những kết quả thay
đổi
Truyền tham trị (ví dụ)
Nhập 2 số và tính trunh bình cộng:
Start
Declare num1, num2, avg as integers
avg = 0
Display “Enter first integer”
Accept num1
Display “Enter second integer”
Accept num2
Avg_func(pass num1 by value, pass num2 by value, pass avg by
value)
Display avg
End
Avg_func(x is an integer, y is an integer, z is an integer)
Start
z = (x + y) / 2
Display z
return
Truyền tham trị (ví dụ)
Avg_func(pass num1 by value, pass num2
by value, pass avg by value)
Biến num1, num2 và avg được truyền bằng
trị vào hàm Avg_func()
Avg_func(x is an integer, y is an integer, z
is an integer)
Cho biết rằng các giá trị num1, num2 và
avg được sao chép vào các biến x, y và z
Lệnh ‘Display z’ hiển thị giá trị trung bình
Lệnh ‘Display avg’ hiển thị giá trị avg gốc
Truyền tham trị (ví dụ 2)
Nhập vào 1 số và thay đổi giá trị của nó trong
hàm:
Start
num is an integer
Display “Enter a number”
Accept num
Display the value in num before change
change(pass num by value)
Display the value in num after change
End
change(var is an integer)
Start
var = 10
Display the value in var
return
Truyền tham trị (ví dụ 2)
change(pass num by value)
Biến num được truyền vào hàm dưới dạng tham trị
change(var is an integer)
Giá trị của num được sao chép vào biến var
Lệnh ‘Display the value in var’ hiển thị giá trị var
là 10
Lệnh ‘Display the value in num after change’ hiển
thị giá trị gốc của num được nhập từ ngưới sử
dụng
Truyền tham chiếu (ví dụ)
Nhập vào 1 số và thay đổi giá trị của nó trong
hàm:
Start
num is an integer
Display “Enter a number”
Accept num
Display the value of num before change
change(pass num by reference)
Display the value of num after change
End
change(var is an integer)
Start
var = 10
Display the value in var
return
Truyền tham chiếu (ví dụ)
change(pass num by reference)
Hàm change nhận 1 tham chiếu đến num
change(var is an integer)
Biến var là 1 tham chiếu tới biến num
Lệnh ‘Display the value in var’ hiển thị giá
trị của var là 10
Lệnh ‘Display the value in num after
change’ cũng sẽ hiển thị giá trị 10 vì biến
var là 1 tham chiếu tới biến num
Phân loại theo công dụng
Tham số có hai công dụng chính:
Cung cấp các giá trị cho hàm
Lưu các kết quả tính toán
Các loại tham số:
Tham số vào: cung cấp giá trị cho hàm
Tham số ra: lưu kết quả tính toán được
Tham số vừa vào, vừa ra
Phải xác định hàm có bao nhiêu tham số
vào, ra
Các tham số ra phải là tham chiếu (con trỏ)
Các tham số vào không muốn thay đổi giá
trị phải là tham trị
Cách viết một hàm
Xác định các thành phần của hàm:
Nội dung của hàm:
• Phân chia nhiều hàm dựa theo chức năng: giúp
cho nội dung được rõ ràng, giảm độ phức tạp và
độ lớn của hàm
• Vị trí khai báo nội dung hàm: các hàm không có
nguyên mẫu phải được khai báo trước main().
Nội dung của hàm có nguyên mẫu có thể được
khai báo ở bất cứ vị trí nào.
Hàm và con trỏ
Nếu đối của hàm là con trỏ kiểu int (float,
double, ) thì tham số thực tương ứng
phải là địa chỉ của biến kiểu int (float,
double, )
Địa chỉ của biến được truyền cho đối con
trỏ tương ứng
Có thể được gán giá trị mới
Hàm và con trỏ
# include
#include
int a,b;
void swap(int a, int b);
main () /* Ham chinh */
{
clrscr();
a=3; b=7;
printf(“\n Truoc khi goi ham: ”)
printf("A= %d ",a);
printf("B= %d ",b);
swap(a,b);
printf("\nSau khi goi ham: A = %d B= %d \n",a,b);
getch();
}
void swap(int a, int b)
{
int temp ;
temp=a;
a=b;
b=temp;
printf("\nTrong ham swap: A= %d B= %d ",a,b);
}
Hàm và con trỏ
# include
#include
int a,b;
void swap(int *a, int *b);
main () /* Ham chinh */
{
clrscr();
a=3; b=7;
printf(“\n Truoc khi goi ham: ”)
printf("A= %d ",a);
printf("B= %d ",b);
swap(&a,&b);
printf("Sau khi goi ham: A = %d B= %d \n",a,b);
getch();
}
void swap(int *a, int *b)
{
int temp ;
temp=*a;
*a=*b;
*b=temp;
printf("\nTrong ham swap A= %d B= %d \n",*a,*b);
}
Tóm tắt
Hàm là chương trình con, gồm các lệnh liên quan
với nhau để thực thi 1 tác vụ cụ thể
Các biến có thể được truyền vào hàm
Những thay đổi giá trị trong hàm sẽ không có ý
nghĩa đối với chương trình chính khi truyền bằng
phương thức truyền tham trị.
Địa chỉ của biến được truyền theo phương thức
truyền tham chiếu
Hàm do người sử dụng định nghĩa là các
chương trình con được viết do người lập trình
Các hàm chuẩn được định nghĩa trước bởi các
cộng cụ lập trình
Bài tập minh họa
#include
#include
void doi(int *a,int b);
main()
{
int x,y;
clrscr();
doi(&x,y=2);
printf("%d %d",x,y);
getch();
}
void doi(int *a,int b)
{
*a=b;
*a+=b++;
}
Bài tập minh họa
#include
int x=2;
int swap(int x,int y);
main()
{
int y=x=1;
swap(x,y);
printf("%d %d",x,y);
}
int swap(int x,int y)
{
int tam;
tam=x;
x=y;
y=tam;
}
Bài tập minh họa
#include
#include
void doi(int *a);
main()
{
int x=0,y=1;
clrscr();
while(x<=y)
doi(&x);
printf("%d %d",y,x);
getch();
}
void doi(int *a)
{
int tam=1;
*a+=tam;
tam++;
}
Bài tập minh họa
#include
int doitri(int *a);
main()
{
int x=1,y=2;
x=doitri(&x);
printf("%d %d",x,y);
}
int doitri(int *a)
{
*a-=1;
*a=++y;
y-=2;
return y;
}
Bài tập minh họa
#include
int y=2;
int doitri(int *a);
main()
{
int x=1;
x=doitri(&x);
printf("%d %d",x,y);
}
int doitri(int *a)
{
*a-=1;
*a=++y;
y-=2;
return y;
}
Bài tập minh họa
#include
#include
int doi(int *a,int *b);
main()
{
int x=1,y=2;
clrscr();
doi(&y,&y);
printf("%d %d",x,y);
getch();
}
int doi(int *a,int *b)
{
*a-=1;
*a=++(*b);
*b-=2;
}
Bài tập minh họa
#include
#include
void ham1(void);
void ham2(int);
void main()
{
clrscr();
ham1();
ham2(3);
return;
}
void ham1(void)
{
printf("Bai tap lap trinh C\n");
}
void ham2(int n)
{
int I;
for(I=0;I<n;I++)
printf(" kinh chao cac ban\n");
}
Bài tập minh họa
#include
int a,b,c,d;
void confuse(int *,int);
void main()
{
a=1;b=2;c=3;d=4;
confuse(&b,c);
printf("\na=%d b=%d c=%d d=%d",a,b,c,d);
confuse(&b,a);
printf("\na=%d b=%d c=%d d=%d",a,b,c,d);
}
void confuse(int *a,int b)
{
int c;
*a=5;b=10;c=4;
printf("\na=%d b=%d c=%d d=%d",*a,b,c,d);
}
Bài tập minh họa
#include
float sohoc(float,float,char);
void main()
{
float x,y;
printf("\n x="); scanf("%f",&x);
printf("\n y="); scanf("%f",&y);
printf("\nTong la:%f",sohoc(x,y,'+'));
printf("\nHieu la:%f",sohoc(x,y,'-'));
printf("\nTich la:%f",sohoc(x,y,'*'));
printf("\nThuong la:%f",sohoc(x,y,'/'));
}
float sohoc(float v1,float v2,char tinh)
{
float ketqua;
switch(tinh)
{
case '+':ketqua=v1+v2; break;
case '-':ketqua=v1-v2; break;
case '*':ketqua=v1*v2; break;
case '/':ketqua=v1/v2; break;
}
return ketqua;
}