CHƯƠNG 4: HÀM• Nội dung Khái niệm hàm Khai báo hàm Lời gọi hàm Nguyên tắc hoạt động của hàm Truyền theo giá trị Phạm vi của biến Hàm kiểu void Truyền theo địa chỉ Khi nào sử dụng đối là
Trang 1CHƯƠNG 4: HÀM
• Nội dung
Khái niệm hàm
Khai báo hàm
Lời gọi hàm
Nguyên tắc hoạt động của hàm
Truyền theo giá trị
Phạm vi của biến
Hàm kiểu void
Truyền theo địa chỉ
Khi nào sử dụng đối là con trỏ
Dùng hàm có giá trị trả về hay hàm kiểu void
Trang 2Khái niệm hàm
• Hàm là một đoạn chương trình thực hiện trọn vẹn một công việc nhất định
Nó chia cắt công việc lớn thành các công việc nhỏ hơn Điều quan trọng là hàm giúp để làm lại những gì đã làm trước đó thay vì phải bắt đầu từ đầu một chức năng nào đó và có thể dùng nhiếu lần trong cùng một đoạn
chương trình
Khai báo hàm
• Cách viết khai báo hàm như sau:
• <kiểu hàm> <tên hàm>(<danh sách các đối sốù>)
• {
• <khai báo thêm các biến>
• <các câu lệnh>
• return <biểu thức>
• }
Trang 3• Trong đó:
Kiểu hàm có thể là một kiểu dữ liệu nào đó (char, int, float, double, …)
hoặc là kiểu void.
Tên hàm bắt buộc phải có đối với mọi hàm
Danh sách đối số (còn gọi là tham số hình thức) thì có thể có hoặc
không tùy thuộc ta định dùng hàm đó làm gì
Phần bao trong dấu ngoặc {} còn gọi là thân hàm, dấu {} là bắt buộc đối với mọi hàm
Khi cần thêm một số biến thì ta cần khai báo thêm Các biến này gọi là biến cục bộ vì chỉ riêng hàm này sử dụng
Phần câu lệnh thực hiện nhiệm vụ của hàm
Câu lệnh return <biểu thức> có thể có hoặc không, khi kiểu hàm không
phải là void thì nó bắt buộc phải có Câu lệnh này có nhiệm vụ trả về
một giá trị cho nơi gọi hàm
Trang 4Lời gọi hàm
• Hàm được sử dụng thông qua lời gọi tới nó Cách viết một lời gọi hàm như sau:
• <tên hàm> (<danh sách tham số thực>)
Số tham số thực phải bằng số đối số
Kiểu của tham số thực phải phù hợp với kiểu của đối tương ứng
Nguyên tắc hoạt động của hàm
Cấp phát bộ nhớ cho các đối số và các biến cục bộ
Gán giá trị của các tham số thực cho các đối tương ứng
Thực hiện các câu lệnh trong thân hàm
Khi gặp câu lệnh return hoặc dấu “}” cuối cùng của thân hàm thì máy
sẽ giải phóng các đối, các biến cục bộ và thóa khỏi hàm
Trang 5• Ví dụ 1: Hàm Max() sau sẽ trả về giá trị lớn nhất của hai số thực
• float Max(float x, float y)
• {
• float res; //Khai báo thêm một biến cục bộ
• if(x > y) res = x;
• else res = y;
• return res;
• }
• void main()
• {
• float a = 3.6, b = 7.2;
• float max;
• max = Max(a, b); /* Lời gọi hàm Max() với hai tham số thực
a và b*/
• <in max>
Trang 6Truyền theo giá trị
Trong cách truyền này, mọi thay đổi vế mặt giá trị của các đối số trong hàm đều không làm thay đổi giá trị của các tham số thực tương ứng trong lời gọi hàm
Trang 7• void HoanVi(float a, float b)
• {
• float tam;
• tam = a;
• }
• void main()
• {
• float x = 3.5, y = 7.6;
• HoanVi(x, y); /*Lời gọi hàm HoanVi() với hai tham số thực là x
và y*/
• <int, x, y>; //x và y không bị thay đổi
• }
Trang 8Phạm vi của biến
Trong ví dụ trên ta thấy rằng trong hàm main() có biến i và trong hàm LuyThua() cũng có biến i, nhưng không có ảnh hưởng gì vì phạm vi
của chúng khác nhau Biến i khai báo trong main() gọi là biến cục bộ
trong main(), nó chỉ có tác dụng trong main() chứ không thể tác động bên ngoài main() được Tương tự như thế đối với hàm LuyThua() Điều quan trọng cần nhớ là các biến được khai báo trong các hàm (biến cục bộ) chỉ tồn tại khi hàm được gọi tới mà thôi, nó sẽ biến mất khi hàm được gọi thực hiện xong
Bên cạnh biến cục bộ còn có các biến nằm ngoài mọi hàm được gọi là
các biến toàn cục, các biến này có thể sử dụng mọi nơi trong chương
trình và tồn tại trong suốt thời gian chương trình thực hiện
Trang 9Hàm kiểu void
• Khi một hàm không trả về một giá trị nào, hàm đó được gọi là hàm kiểu void
• Ví dụ:
• void In(int x, int y)
• {
• printf(“%d, %d\n”, x, y);
• }
• void main()
• {
• for(i = 1; i <= 10; i++)
• In(i, 2*i); /*Lời gọi hàm In() với hai tham số thực là i và
2*i */
Trang 10Truyền theo địa chỉ
• Khái niệm con trỏ và địa chỉ
Khi một biến được khai báo, ba thuộc tính cơ bản sau đây được liên kết với
nó Đó là:
Tên định danh của biến
Kiểu dữ liệu liên quan
Địa chỉ trong bộ nhớ
• Ví dụ 1: Với khai báo
• int n;
• thì n là tên định danh của biến, có kiểu là số nguyên dạng int và được lưu trữ đâu đó trong bộ nhớ máy tính Khi đó để truy cập đến biến, chúng ta sử dụng tên định danh của nó
Trang 11 Con trỏ là biến dùng để chứa địa chỉ của biến khác Có nhiều loại biến con trỏ chẳng hạn như con trỏ kiểu int dùng để chứa địa chỉ biến kiểu int, con trỏ kiểu float dùng để chứa địa chỉ biến kiểu float, …
• Cú pháp khai báo con trỏ như sau:
• <tên kiểu> *<tên biến con trỏ>;
• Ví dụ 2:
• int *p1; //p1 là biến con trỏ kiểu int
• float *p2 // p2 là biến con trỏ kiểu float
• char *p3; //p3 là biến con trỏ kiểu char
Trang 12• Giả sử có một biến x và có một con trỏ p chứa địa chỉ biến x, thì cách viết x
và *p là tương đương nhau trong mọi ngữ cảnh
• Ví dụ 3:
• void main()
• {
• int x = 10, y = 20;
• int *p1, *p2; // khai báo hai con trỏ kiểu int
<int x, y>
p1 = &x; //p1 chứa địa chỉ của x (trỏ tới x)
• p2 = &y;
• *p1 += 5; // x += 5
• <int x, y>
• }
•
Trang 13Truyền theo địa chỉ
Trong cách truyền này, mọi thay đổi về mặt giá trị của các đối số trong hàm đều làm thay đổi giá trị của các tham số thực tương ứng trong lời gọi hàm
Khi sử dụng cách truyền theo địa chỉ thì trong định nghĩa của hàm ta cần khai báo đối số là một biến con trỏ
Trang 14• Ví dụ 4: Hoán vị hai số thực
• void HoanVi(float *a, float *b)
• {
• float tam;
• tam = *a;
• }
• void main()
• {
• float x = 3.5, y = 7.6;
• HoanVi(&x, &y); /*Lời gọi hàm HoanVi() với hai tham số thực là
&x và &y */
• <int, x, y>; //x và y đã bị thay đổi
• }
Trang 15Khi nào sử dụng đối là con trỏ
Trong đối số của hàm ta có thể chia làm hai loại: loại thứ nhất gồm các đối
chứa giá trị đã biết ta gọi chúng là các đối vào, loại thứ hai gốm các đối chúa kết quả nhận được ta gọïi chúng là các đối ra Các đối ra phải là con
trỏ
Dùng hàm có giá trị trả về hay hàm kiểu void
Dùng hàm có giá trị trả về đối với các hàm có tính chất giống hàm toán học
và trả về một giá trị duy nhất hoặc đối với các hàm mà lời gọi nó cần xuất hiện trong một biểu thức
Dùng hàm kiểu void đối với các hàm có tính chất thực hiện một hành động nào đó hoặc đối với các hàm có tính chất tính toán nhưng trả về cùng lúc nhiều giá trị
Trang 16Nguyên mẫu hàm
Về nguyên tắc khi gọi một hàm thì hàm đó phải được định nghĩa trước, nếu không chương trình sẽ bị lỗi
Tuy nhiên cũng có thể gọi một hàm chưa đươc định nghĩa trước bằng cách khai báo trước nguyên mẫu hàm Nguyên mẫu hàm thực chất là dòng đầu của hàm và thêm vào dấu chấm phẩy
Trong nguyên mẫu hàm có thể bỏ tên các đối
Trang 17• Ví dụ 4: Hoán vị hai số thực
• //khai báo nguyên mẫu hàm
• void HoanVi(float *a, float *b);
• void main()
• {
• float x = 3.5, y = 7.6;
• HoanVi(&x, &y); // truyền theo địa chỉ
• <int, x, y>;
• }
• void HoanVi(float *a, float *b)
• {
• float tam;
• tam = *a;