Cú pháp: kiểu_dữ_liệu tên_hàm(danh_sách_tham_số) { Thân hàm; } Trong đó,
o kiểu_dữ_liệu: là kiểu dữ liệu mà hàm trả về.
o tên_hàm: là tên của hàm, do người lập trình đặt. Tên hàm không được chứa
kí tự đặc biệt, không được bắt đầu bằng số, không chứa kí tự trắng, không trùng với từ khóa.
o danh_sách_tham_số: là danh sách các tham số dùng như các biến cục bộ.
Nếu có nhiều tham số, thì chúng sẽ được phân tách theo các dấu phẩy.
o Thân hàm: là nội dung mà người lập trình xây dựng nên. Nếu hàm trả về
kiểu dữ liệu khác void, ta cần sử dụng lệnh return để trả về biến chứa kết quả và có cùng kiểu dữ liệu với kiểu dữ liệu của hàm. Nếu hàm trả về kiểu dữ liệu void thì điều này là không cần thiết.
Ví dụ Kết quả
#include <iostream> using namespace std; int add(int a, int b) {
return a+b;
C + + } int main() { cout<<add(1, 2); return 0; }
Giải thích: Mọi chương trình trong C++ luôn bắt đầu bởi hàm main. Điều đó có
nghĩa là các lệnh trong hàm main sẽ được thực thi một cách tuần tự. Đối tượng cout sẽ in giá trị của hàm add(1,2). Khi gọi đến hàm add, nó sẽ ánh xạ đến hàm add đã được khai báo ở trên, nó chỉ tạo ra một lời gọi hàm đến hàm đã được xây dựng có tên tương ứng (chúng ta cần lưu ý đến điều này để phân biệt với khái niệm hàm nội tuyến sẽ được tìm hiểu trong các mục tiếp theo). Với a, b là các tham số hình thức, chúng sẽ được thay thế bằng các giá trị cụ thể là 1 và 2. Hàm add này sẽ trả về giá trị là tổng của a và b nhờ từ khóa return.
Cách khai báo hàm trong ví dụ trên được gọi là khai báo trực tiếp. Chúng ta cũng còn một cách khai báo hàm gián tiếp nữa, mà ta thường gọi là khai báo hàm prototype như sau:
Ví dụ Kết quả
#include <iostream> using namespace std; int add(int a, int b); int main()
{
cout<<add(1, 2); return 0;
}
int add(int a, int b) {
return a+b; }
C
+
+
Trong khai báo hàm dạng này, cấu trúc khai báo hàm khuyết phần thân hàm. Chỉ có khai báo phần tên của hàm theo cú pháp chuẩn. Ta có thể đặt hàm xây dựng hoàn chỉnh ở bất kì vị trí nào. Cách khai báo hàm prototype có nhiều ưu điểm: - Không cần quan tâm đến thứ tự khai báo hàm. Nếu không sử dụng khai báo prototype, thì hàm khai báo sau mới được phép gọi hàm khai báo trước nó. Điều ngược lại là không được phép. Nhưng đối với khai báo prototype thì ta hoàn toàn không cần quan tâm đến điều này.
- Ta có thể tách phần khai báo prototype và đặt nó vào trong một tập tin mới, thường là tập tin tiêu đề .h (với tên gọi tùy vào người lập trình quy định), phần thân hàm lại chứa trong một tệp khác, thường là .cpp hoặc trong chính tệp chứa chương trình chính. Cách làm này giúp chương trình sáng sủa hơn rất nhiều. Trong các dự án lập trình lớn, người ta thường phân tách theo dạng này. Chúng ta sẽ xét ví dụ minh họa sau.
Trong ví dụ minh họa này, dự án của tôi gồm có hai tệp: tieude.h để chứa khai báo prototype và main.cpp để chứa thân hàm và hàm main.
Đối với Codeblocks, hãy thực hiện theo các bước sau:
- Tạo mới một dự án C++ và lưu lại. Trong dự án này, mặc định Codeblocks sẽ tạo một tệp main.cpp.
- Vào New > File > chọn C/C++ header. Sau đó, hãy chọn vị trí để lưu trữ tệp tiêu đề (thông thường, ta nên tạo các thư mục khác nhau để lưu tệp .h cũng như tệp .cpp như tôi đã trình bày ở trên).
Đối với Eclipse, thực hiện như sau:
- Kích chuột phải vào thư mục cần đặt tệp .h, chọn New > Header File. - Kích chuột phải vào thư mục cần đặt tệp .cpp, chọn New > Source File.
Đối với Visual Studio 2010, kích chuột phải vào tên dự án, chọn Add New
Item. Sau đó chọn header file .h.
Tệp tieude.h Tệp main.cpp
#ifndef TIEUDE_H_INCLUDED #define TIEUDE_H_INCLUDED int sum(int, int);
void showmsg(void); #endif // TIEUDE_H_INCLUDED #include <iostream> #include "tieude.h" using namespace std; int main() { showmsg(); return 0; } void showmsg(){ cout<<sum(1, 3);
C
+
+
}
int sum(int a, int b){ return a+b;
}
Trong tệp tieude.h, ta chỉ việc nhập các khai báo prototype vào giữa #define và #endif. Trong tệp main.cpp, ta cần bổ sung khai báo thư viện #include “tieude.h”. Chú ý rằng, tên tệp tiêu đề nằm trong dấu nháy kép “”, mà không phải là dấu <>. Các hàm trong chương trình chính có thể sử dụng mà không cần quan tâm đến thứ tự khai báo. Như chúng ta thấy, các hàm khai báo sau hàm main (điều này chỉ có thể được phép đối với khai báo prototype). Hàm showmsg khai báo trước hàm sum nhưng có thể gọi được hàm sum. Thứ tự tiêu đề của hàm trong tệp tiêu đề hoàn toàn không quan trọng và nó không ảnh hưởng việc sử dụng các hàm theo thứ tự trước sau.
Lưu ý:
Khi sử dụng khai báo prototype trên các tập tin .h, ta cần lưu ý, nếu dự án có sử dụng namespace, ví dụ std, ta chỉ có thể sử dụng cú pháp truy cập std:: mà không được sử dụng using namespace std trong tệp .h này.
Nếu tệp .cpp và tệp .h nằm trong cùng thư mục, thì phần #include trong tệp cpp có thể viết tên tệp tiêu đề trong dấu “”. Nếu chúng không nằm trong cùng thư mục, ta cần chỉ đường dẫn tương đối cho nó. Ví dụ tệp headers.h nằm trong thư mục headers và tệp main.cpp nằm trong thư mục cpps. Nếu tệp headers.h là tệp tiêu đề của tệp main.cpp, ta cần include nó trong main.cpp. Giả sử headers và cpps nằm trong cùng thư mục src. Khi đó, trong tệp main.cpp, hãy khai báo như sau: #include“../headers/headers.h”. Trong đó, dấu ../ để dịch lùi một mức trong cấu trúc cây thư mục (dịch lùi từ thư mục headers một mức chính là thư mục src), sau đó là headers/headers.h.
1.7.2. Phạm vi tác dụng của biến
Như tôi đã giới thiệu ở trên, biến toàn cục là những biến được khai báo ngoài tất cả các hàm (hay không bao trong bất kì dấu {} nào). Các biến này có tác dụng trong toàn bộ chương trình. Ta có thể gọi nó trong hàm main, hay trong các hàm khác. Ngược lại, những biến còn lại gọi là các biến cục bộ. Những biến cục bộ được khai báo trong phạm vi nào (được xác định nhờ dấu {}) thì chỉ có tác dụng trong phạm vi đó mà thôi.
Ví dụ Giải thích
#include <iostream> using namespace std; int global;
int add(int a, int b)
- Biến global là biến toàn cục, nó có tác dụng trong toàn bộ chương trình. Ta có thể sử dụng nó trong hàm main, hàm add…
- Biến local, local1, local2 là các biến cục bộ. Biến local được khai
C + + { local result = a + b; return result; } int main() { int local1; if(local1>0) { int local2; } return 0; }
báo trong hàm add, nó có phạm vi tác dụng trong phạm vi của hàm này. Biến cục bộ local1 được khai báo trong hàm main. Nó cũng chỉ có tác dụng trong hàm main. Biến local2 được khai báo trong phạm vi tác dụng của câu lệnh if, nó chỉ có tác dụng trong khối lệnh này. Nếu ta gọi biến này ngoài khối lệnh của if, chương trình dịch sẽ báo lỗi.