C++: Bài 17. Hàm (Function)

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Hàm (function) là một nhóm các câu lệnh dùng để thực hiện một tác vụ (một công việc) cụ thể. Mọi chương trình C++ đều có ít nhất một hàm, đó là hàm main() và tất cả các chương trình đơn giản nhất đều có thể định nghĩa các hàm bổ sung.

Bạn có thể chia mã chương trình của bạn thành các hàm riêng biệt. Cách bạn phân chia mã chương trình thành các hàm khác nhau là tùy thuộc vào bạn, nhưng về mặt logic, việc phân chia thường là sao cho mỗi chức năng thực hiện một nhiệm vụ (công việc) cụ thể.

Ta cần khai báo hàm cho trình biên dịch biết về tên, kiểu trả về và các tham số của hàm, và cần định nghĩa hàm để cung cấp đoạn mã xử lý công việc.

Thư viện chuẩn C++ cung cấp nhiều hàm tích hợp sẵn mà chương trình của bạn có thể gọi. Ví dụ, hàm strcat() để nối hai chuỗi, hàm memcpy() để sao chép một vị trí bộ nhớ sang một vị trí khác và nhiều hàm khác.

Một hàm được biết đến với nhiều tên khác nhau như một phương thức hoặc một quy trình con hoặc một thủ tục, v.v.

Định nghĩa hàm

Dạng tổng quát của định nghĩa hàm trong C++ như sau:

kiểu_trả_về tên_hàm(danh_sách_tham_số) {
  khối_lệnh_xử_lý_công_việc
  return giá_trị;
}

trong đó,

  • kiểu_trả_về: một hàm chỉ có thể trả về một giá_trị. kiểu_trả_về là một kiểu bất kỳ phù hợp với giá_trị mà bạn muốn hàm trả về. Nếu kiểu_trả_về là void thì không có lệnh return giá_trị; hoặc có thể viết lệnh return; , nếu khác void thì bắt buộc phải có lệnh return giá_trị; . giá_trị sẽ được trả về nơi hàm được gọi.
  • tên_hàm: do ta tự đặt, thương tên_hàm được đặt theo quy tắc lạc đà, ví dụ như nhapLieu, hienThi, tinhBietThucDelta.
  • danh_sách_tham số: dùng để tiếp nhận dữ liệu từ lời gọi hàm. Nếu một hàm cần có dữ liệu để xử lý công việc thì danh_sách_tham_số là cần thiết để tiếp nhận; còn nếu hàm không cần nhận dữ liệu thì sẽ không có danh_sách_tham_số.
  • return giá_trị; : Nếu kiểu_trả_về là void thì không có lệnh return giá_trị; hoặc lệnh sẽ là return; , còn nếu kiểu_trả_về khác void thì bắt buộc phải có lệnh return giá_trị; .

Ví dụ

Định nghĩa hàm có tên demo(), kiểu_trả_về và void (và vì vậy không có lệnh return giá_trị;), không có danh_sách_tham_số.

void demo() {

  printf("Ban dang trong ham demo()");

}

Định nghĩa hàm có tên tinhTong(), kiểu_trả_về là void, danh_sách_tham_số gồm 2 tham số a và b kiểu float để tiếp nhận 2 dữ liệu để tính tổng.

void tinhTong(float a, float b){

  printf("%g + %g = %g", a, b, a+b);

}

Định nghĩa hàm có tên tinhBietThucDelta(), kiểu_trả_về là double (và vì vậy phải có lệnh return giá_trị;), danh_sách_tham_số gồm 3 tham số a, b, c kiểu float để tiếp nhậ 3 hệ số a, b, c tương ứng để tính delta.

double tinhBietThucDelta(float a, float b, float c){

  return b*b - 4*a*c;

}

Khai báo hàm

Một khai báo hàm cho trình biên dịch biết về tên hàm và cách gọi hàm. Phần thân thực của hàm có thể được định nghĩa riêng biệt.

Một khai báo hàm có các phần sau:

kiểu_trả_về tên_hàm(danh_sách_tham_số);

Ví dụ như hàm tinhBietThucDelta() ở ví dụ trên thì khai báo hàm là:

double tinhBietThucDelta(float a, float b, float c);

Hoặc ta cũng không cần phải có khai báo tên của từng tham số, mà chỉ cần có kiểu dữ liệu. Dưới đây là khai báo tương đương với khai báo trên:

double tinhBietThucDelta(float, float, float);

Khai báo hàm là bắt buộc khi bạn định nghĩa một hàm trong một tệp nguồn và bạn gọi hàm đó trong một tệp khác. Trong trường hợp này, bạn nên khai báo hàm ở đầu tệp gọi hàm.

Gọi một hàm

Khi tạo một hàm, bạn đưa ra định nghĩa về những gì hàm phải làm. Để sử dụng một hàm, bạn sẽ phải gọi (yêu cầu) hàm đó.

Khi một chương trình gọi một hàm thì quyền điều khiển chương trình sẽ được chuyển sang hàm được gọi. Một hàm được gọi thực hiện công việc đã xác định và khi câu lệnh trả về của nó được thực thi hoặc khi gặp dấu đóng ngoặc xoắn (}) kết thúc hàm, nó sẽ trả lại quyền điều khiển chương trình về nơi hàm được gọi.

Để gọi một hàm, bạn chỉ cần truyền đối số (nếu có) cùng với tên hàm và nếu hàm trả về một giá trị, thì bạn có thể lưu trữ giá trị trả về. Ví dụ:

#include<iostream>
using  namespace std;

// khai báo hàm
double tinhBietThucDelta(float, float, float);

main(){
  // khai báo biến cc b:
  float a = 1;
  float b = 3;
  float c = 2;
  double delta;

  // gi hàm đ nhn giá tr delta.
  delta = tinhBietThucDelta(a,b,c);
  cout << "Delta = " << delta << endl;

  return 0;
}

// đnh nghĩa hàm tr v delta
double tinhBietThucDelta(float a, float b, float c){
  // khai báo biến cc b  double delta;

  return b*b - 4*a*c; // trả về giá trị của biểu thức
}

Kết quả:

Delta = 1

Đối số hàm

Nếu một hàm sử dụng các đối số, nó phải khai báo các biến chấp nhận giá trị của các đối số. Các biến này được gọi là các tham số chính thức của hàm.

Các tham số chính thức hoạt động giống như các biến cục bộ khác bên trong hàm và được tạo khi nhập vào hàm và bị hủy khi thoát khỏi hàm.

Trong khi gọi một hàm, có một số cách mà các đối số có thể được truyền cho một hàm:

Các cách gọi hàm
Gọi theo giá trị

Cách thức này sao chép giá trị thực của một đối số vào tham số chính thức của hàm. Trong trường hợp này, các thay đổi được thực hiện đối với tham số bên trong hàm không ảnh hưởng đến đối số.

Gọi bằng con trỏ

Cách thức này sao chép địa chỉ của một đối số vào tham số chính thức. Bên trong hàm, địa chỉ được sử dụng để truy cập đối số thực được sử dụng trong lệnh gọi. Điều này có nghĩa là các thay đổi được thực hiện đối với tham số sẽ ảnh hưởng đến đối số.

Gọi bằng tham chiếu

Cách thức này sao chép tham chiếu của một đối số vào tham số chính thức. Bên trong hàm, tham chiếu được sử dụng để truy cập đối số thực được sử dụng trong lệnh gọi. Điều này có nghĩa là các thay đổi được thực hiện đối với tham số sẽ ảnh hưởng đến đối số.

Theo mặc định, C++ sử dụng lệnh gọi theo giá trị để truyền các đối số. Nói chung, điều này có nghĩa là mã lệnh trong một hàm không thể thay đổi các đối số được sử dụng để gọi hàm và ví dụ đã đề cập ở trên trong khi gọi hàm tinhBietThucDelta() được sử dụng cùng một phương thức.

Giá trị mặc định cho các tham số

Khi bạn định nghĩa một hàm, bạn có thể chỉ định một giá trị mặc định cho mỗi tham số cuối cùng. Giá trị này sẽ được sử dụng nếu đối số tương ứng bị bỏ trống khi gọi hàm.

Điều này được thực hiện bằng cách sử dụng toán tử gán và gán giá trị cho các tham số trong định nghĩa hàm. Nếu một giá trị cho tham số đó không được truyền khi hàm được gọi, giá trị đã cho mặc định sẽ được sử dụng, nhưng nếu một giá trị được chỉ định, giá trị mặc định này sẽ bị bỏ qua và giá trị đã truyền được sử dụng thay thế. Hãy xem xét ví dụ sau:

#include<iostream>
using  namespace std;

int sum(int a, int b = 20) {
  int result ;
  result = a + b;

  return result;
}

main() {
  // khai báo biến cc b:
  int a =  100 ;
  int b =  200 ;
  int result;

  // gi mt hàm đ cng các giá tr.
  result = sum(a,b);
  cout << "Tong = " << result << endl;

  // gi li mt hàm như sau.
  result = sum(a);
  cout << "Tong = " << result << endl;

  return 0;
}

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

Tong = 300 
Tong = 120
» Tiếp: Bài 18. Biến toàn cục và biến cục bộ
« Trước: Bài 16. Vòng lặp do-while
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!