C++
  • Home
  • Học lập trình
    • All
    • Học C++
    Quick Sort – Thuật toán sắp xếp đột phá trong thế kỉ XX

    Quick Sort – Thuật toán sắp xếp đột phá trong thế kỉ XX

    Lập trình Backend là gì? Những điều Backend Developer nên biết

    Lập trình Backend là gì? Những điều Backend Developer nên biết

    Top 7 website luyện thuật toán chất lượng nhất năm 2023 cho IT

    Top 7 website luyện thuật toán chất lượng nhất năm 2023 cho IT

    hướng dẫn cài đặt visual studio code lập trình c++ chi tiết

    Cài Đặt Visual Studio Code Lập Trình C++ Chi Tiết Đơn Giản 2024

    học lập trình c++ thì làm được gì

    Học Lập Trình C++ Thì Làm Được Gì?

    Sự khác nhau giữa struct và class trong C++

    Sự Khác Nhau Giữa Struct Và Class Trong C++

    Sự khác nhau giữa tham chiếu và con trỏ c++

    Sự Khác Nhau Giữa Tham Chiếu Và Con Trỏ Trong C++

    • Học C++
  • Reviews
    Top 7 công cụ tạo website không cần code

    Top 7 Công Cụ Tạo Website Không Cần Code Miễn Phí

    Top 7 website luyện thuật toán chất lượng nhất năm 2023 cho IT

    Top 7 website luyện thuật toán chất lượng nhất năm 2023 cho IT

  • Phần mềm PC
  • App/Ứng dụng
  • Game
  • Hướng dẫn
    • PC
    • Mobile Tips
No Result
View All Result
  • Home
  • Học lập trình
    • All
    • Học C++
    Quick Sort – Thuật toán sắp xếp đột phá trong thế kỉ XX

    Quick Sort – Thuật toán sắp xếp đột phá trong thế kỉ XX

    Lập trình Backend là gì? Những điều Backend Developer nên biết

    Lập trình Backend là gì? Những điều Backend Developer nên biết

    Top 7 website luyện thuật toán chất lượng nhất năm 2023 cho IT

    Top 7 website luyện thuật toán chất lượng nhất năm 2023 cho IT

    hướng dẫn cài đặt visual studio code lập trình c++ chi tiết

    Cài Đặt Visual Studio Code Lập Trình C++ Chi Tiết Đơn Giản 2024

    học lập trình c++ thì làm được gì

    Học Lập Trình C++ Thì Làm Được Gì?

    Sự khác nhau giữa struct và class trong C++

    Sự Khác Nhau Giữa Struct Và Class Trong C++

    Sự khác nhau giữa tham chiếu và con trỏ c++

    Sự Khác Nhau Giữa Tham Chiếu Và Con Trỏ Trong C++

    • Học C++
  • Reviews
    Top 7 công cụ tạo website không cần code

    Top 7 Công Cụ Tạo Website Không Cần Code Miễn Phí

    Top 7 website luyện thuật toán chất lượng nhất năm 2023 cho IT

    Top 7 website luyện thuật toán chất lượng nhất năm 2023 cho IT

  • Phần mềm PC
  • App/Ứng dụng
  • Game
  • Hướng dẫn
    • PC
    • Mobile Tips
No Result
View All Result
C++
No Result
View All Result
Home Học lập trình Học C++

Chức năng trong C++

admin by admin
July 5, 2023
in Học C++
0 0
0
0
SHARES
0
VIEWS
Share on FacebookShare on Twitter

Chức năng

Các chức năng cho phép cấu trúc các chương trình trong các phân đoạn mã để thực hiện các tác vụ riêng lẻ.

Trong C++, hàm là một nhóm các câu lệnh được đặt tên và có thể được gọi từ một số điểm của chương trình. Cú pháp phổ biến nhất để định nghĩa một hàm là: Trong đó:

– là loại giá trị được hàm trả về.
– là mã định danh mà hàm có thể được gọi.
– (nhiều như cần thiết): Mỗi tham số bao gồm một loại theo sau là một mã định danh, với mỗi tham số được phân tách với tham số tiếp theo bằng dấu phẩy. Mỗi tham số trông rất giống một khai báo biến chính quy (ví dụ: ), và trên thực tế hoạt động trong hàm như một biến chính quy cục bộ của hàm. Mục đích của các tham số là cho phép truyền các đối số đến hàm từ vị trí mà nó được gọi đến.
– là cơ thể của chức năng. Nó là một khối các câu lệnh được bao quanh bởi dấu ngoặc nhọn { } chỉ định chức năng thực sự làm gì.

Chúng ta hãy xem một ví dụ: type name ( parameter1, parameter2, ...) { statements }
typenameparametersint xstatements


// function example
#include <iostream>
using namespace std;

int addition (int a, int b)
{
  int r;
  r=a+b;
  return r;
}

int main ()
{
  int z;
  z = addition (5,3);
  cout << "The result is " << z;
}
The result is 8

Chương trình này được chia thành hai hàm: và . Hãy nhớ rằng bất kể thứ tự mà chúng được xác định, một chương trình C ++ luôn bắt đầu bằng cách gọi . Trên thực tế, là hàm duy nhất được gọi tự động và mã trong bất kỳ hàm nào khác chỉ được thực thi nếu hàm của nó được gọi từ (trực tiếp hoặc gián tiếp).

Trong ví dụ trên, bắt đầu bằng cách khai báo biến kiểu , và ngay sau đó, nó thực hiện lệnh gọi hàm đầu tiên: nó gọi . Lệnh gọi đến một hàm tuân theo một cấu trúc rất giống với khai báo của nó. Trong ví dụ trên, lệnh gọi đến có thể được so sánh với định nghĩa của nó chỉ vài dòng trước đó:


Các tham số trong khai báo hàm có sự tương ứng rõ ràng với các đối số được truyền trong lệnh gọi hàm. Cuộc gọi chuyển hai giá trị và , đến hàm; Chúng tương ứng với các tham số và , được khai báo cho hàm .

Tại thời điểm mà hàm được gọi từ bên trong chính, điều khiển được chuyển đến hàm : ở đây, việc thực thi được dừng lại và sẽ chỉ tiếp tục khi hàm kết thúc. Tại thời điểm gọi hàm, giá trị của cả hai đối số ( và ) được sao chép vào các biến cục bộ và trong hàm.

Sau đó, bên trong , một biến cục bộ khác được khai báo (), và bằng biểu thức , kết quả của cộng được gán cho ; Trong đó, đối với trường hợp này, trong đó là 5 và là 3, có nghĩa là 8 được gán cho .

Câu lệnh cuối cùng trong hàm:additionmainmainmainmainmainzintadditionaddition53abadditionadditionmainaddition53int aint badditionint rr=a+babrabr

1
return r;

Kết thúc hàm , và trả về điều khiển trở lại điểm mà hàm được gọi; Trong trường hợp này: để chức năng . Tại thời điểm chính xác này, chương trình tiếp tục khóa học quay trở lại chính xác tại cùng thời điểm mà nó bị gián đoạn bởi cuộc gọi đến . Nhưng ngoài ra, vì có kiểu trả về, lệnh gọi được đánh giá là có giá trị và giá trị này là giá trị được chỉ định trong câu lệnh trả về đã kết thúc : trong trường hợp cụ thể này, giá trị của biến cục bộ , tại thời điểm câu lệnh có giá trị là 8.


Do đó, lệnh gọi đến là một biểu thức có giá trị được hàm trả về và trong trường hợp này, giá trị đó, 8, được gán cho . Như thể toàn bộ hàm gọi () đã được thay thế bằng giá trị mà nó trả về (tức là 8).

Sau đó, main chỉ cần in giá trị này bằng cách gọi: additionmainmainadditionadditionadditionrreturnadditionzaddition(5,3)

1
cout << "The result is " << z;

Một hàm thực sự có thể được gọi nhiều lần trong một chương trình và đối số của nó tự nhiên không chỉ giới hạn ở các nghĩa đen:


// function example
#include <iostream>
using namespace std;

int subtraction (int a, int b)
{
  int r;
  r=a-b;
  return r;
}

int main ()
{
  int x=5, y=3, z;
  z = subtraction (7,2);
  cout << "The first result is " << z << '\n';
  cout << "The second result is " << subtraction (7,2) << '\n';
  cout << "The third result is " << subtraction (x,y) << '\n';
  z= 4 + subtraction (x,y);
  cout << "The fourth result is " << z << '\n';
}
The first result is 5
The second result is 5
The third result is 2
The fourth result is 6

Tương tự như hàm trong ví dụ trước, ví dụ này định nghĩa một hàm, chỉ đơn giản trả về sự khác biệt giữa hai tham số của nó. Lần này, gọi hàm này nhiều lần, chứng minh nhiều cách khả thi hơn trong đó một hàm có thể được gọi.

Hãy kiểm tra từng cuộc gọi này, lưu ý rằng mỗi cuộc gọi hàm tự nó là một biểu thức được đánh giá là giá trị mà nó trả về. Một lần nữa, bạn có thể nghĩ về nó như thể lệnh gọi hàm tự nó được thay thế bằng giá trị trả về:additionsubtractmain

1
2
z = subtraction (7,2);
cout << "The first result is " << z;

Nếu chúng ta thay thế lệnh gọi hàm bằng giá trị mà nó trả về (tức là 5), chúng ta sẽ có:

1
2
z = 5;
cout << "The first result is " << z;

Với quy trình tương tự, chúng ta có thể giải thích:

1
cout << "The second result is " << subtraction (7,2);

như:

1
cout << "The second result is " << 5;

vì 5 là giá trị được trả về bởi .

Trong trường hợp:subtraction (7,2)

1
cout << "The third result is " << subtraction (x,y);

Các đối số được truyền cho phép trừ là các biến thay vì nghĩa đen. Điều đó cũng hợp lệ, và hoạt động tốt. Hàm được gọi với các giá trị và có tại thời điểm gọi: 5 và 3 tương ứng, kết quả là trả về 2.

Cuộc gọi thứ tư lại tương tự:xy

1
z = 4 + subtraction (x,y);

Bổ sung duy nhất là bây giờ cuộc gọi hàm cũng là một toán hạng của một phép cộng. Một lần nữa, kết quả giống như khi cuộc gọi hàm được thay thế bằng kết quả của nó: 6. Lưu ý, nhờ thuộc tính giao hoán của phép cộng, ở trên cũng có thể được viết là:

1
z = subtraction (x,y) + 4;

Với kết quả chính xác tương tự. Cũng lưu ý rằng dấu chấm phẩy không nhất thiết phải đi sau lệnh gọi hàm, nhưng, như mọi khi, ở cuối toàn bộ câu lệnh. Một lần nữa, logic đằng sau có thể dễ dàng được nhìn thấy lại bằng cách thay thế các lệnh gọi hàm bằng giá trị trả về của chúng:

1
2
z = 4 + 2;    // same as z = 4 + subtraction (x,y);
z = 2 + 4;    // same as z = subtraction (x,y) + 4; 

Chức năng không có loại. Việc sử dụng khoảng trống

Cú pháp hiển thị ở trên cho các hàm:

Yêu cầu khai báo bắt đầu bằng một kiểu. Đây là loại giá trị được trả về bởi hàm. Nhưng nếu hàm không cần trả về giá trị thì sao? Trong trường hợp này, loại được sử dụng là , là một loại đặc biệt để đại diện cho sự vắng mặt của giá trị. Ví dụ: một hàm chỉ cần in thư có thể không cần trả về bất kỳ giá trị nào: type name ( argument1, argument2 ...) { statements }
void


// void function example
#include <iostream>
using namespace std;

void printmessage ()
{
  cout << "I'm a function!";
}

int main ()
{
  printmessage ();
}
I'm a function!

void cũng có thể được sử dụng trong danh sách tham số của hàm để xác định rõ ràng rằng hàm không nhận tham số thực tế khi được gọi. Ví dụ: có thể được khai báo là:printmessage

1
2
3
4
void printmessage (void)
{
  cout << "I'm a function!";
}

Trong C++, một danh sách tham số trống có thể được sử dụng thay vì có cùng ý nghĩa, nhưng việc sử dụng trong danh sách đối số đã được phổ biến bởi ngôn ngữ C, trong đó đây là một yêu cầu.

Một cái gì đó trong mọi trường hợp không phải là tùy chọn là dấu ngoặc đơn theo tên hàm, không phải trong khai báo của nó cũng như khi gọi nó. Và ngay cả khi hàm không nhận tham số, ít nhất một cặp dấu ngoặc đơn trống sẽ luôn được gắn vào tên hàm. Xem cách được gọi trong ví dụ trước:voidvoidprintmessage

1
printmessage ();

Dấu ngoặc đơn là những gì phân biệt các chức năng với các loại khai báo hoặc tuyên bố khác. Sau đây sẽ không gọi hàm:

1
printmessage;

Giá trị trả về của chính

Bạn có thể nhận thấy rằng kiểu trả về là , nhưng hầu hết các ví dụ trong chương này và các chương trước không thực sự trả về bất kỳ giá trị nào từ .

Vâng, có một nhược điểm: Nếu việc thực thi kết thúc bình thường mà không gặp phải một câu lệnh, trình biên dịch giả định hàm kết thúc bằng một câu lệnh trả về ngầm:mainintmainmainreturn

1
return 0;

Lưu ý rằng điều này chỉ áp dụng cho chức năng vì lý do lịch sử. Tất cả các hàm khác có kiểu trả về sẽ kết thúc bằng một câu lệnh thích hợp bao gồm giá trị trả về, ngay cả khi giá trị này không bao giờ được sử dụng.

Khi trả về số 0 (ngầm hoặc rõ ràng), môi trường diễn giải nó là chương trình đã kết thúc thành công. Các giá trị khác có thể được trả về bởi , và một số môi trường cung cấp quyền truy cập vào giá trị đó cho người gọi theo một cách nào đó, mặc dù hành vi này không bắt buộc cũng như không nhất thiết phải di động giữa các nền tảng. Các giá trị cho điều đó được đảm bảo được diễn giải theo cùng một cách trên tất cả các nền tảng là:mainreturnmainmainmain

Bởi vì tuyên bố ngầm cho là một ngoại lệ khó khăn, một số tác giả coi đó là thực hành tốt để viết tuyên bố rõ ràng.return 0;main

Các đối số được truyền theo giá trị và bằng tham chiếu

Trong các hàm được thấy trước đó, các đối số luôn được truyền theo giá trị. Điều này có nghĩa là, khi gọi một hàm, những gì được truyền đến hàm là các giá trị của các đối số này tại thời điểm của cuộc gọi, được sao chép vào các biến được biểu thị bằng các tham số hàm. Ví dụ: hãy:

1
2
int x=5, y=3, z;
z = addition ( x, y );

Trong trường hợp này, phép cộng hàm được truyền 5 và 3, là bản sao của các giá trị của và , tương ứng. Các giá trị này (5 và 3) được sử dụng để khởi tạo các biến được đặt làm tham số trong định nghĩa của hàm, nhưng bất kỳ sửa đổi nào của các biến này trong hàm đều không ảnh hưởng đến các giá trị của các biến x và y bên ngoài nó, bởi vì x và y không được chuyển đến hàm trong cuộc gọi, mà chỉ sao chép các giá trị của chúng tại thời điểm đó.


Tuy nhiên, trong một số trường hợp nhất định, có thể hữu ích khi truy cập một biến bên ngoài từ bên trong một hàm. Để làm điều đó, các đối số có thể được truyền bằng tham chiếu, thay vì theo giá trị. Ví dụ: hàm trong mã này sao chép giá trị của ba đối số của nó, khiến các biến được sử dụng làm đối số thực sự được sửa đổi bởi lệnh gọi:xyduplicate


// passing parameters by reference
#include <iostream>
using namespace std;

void duplicate (int& a, int& b, int& c)
{
  a*=2;
  b*=2;
  c*=2;
}

int main ()
{
  int x=1, y=3, z=7;
  duplicate (x, y, z);
  cout << "x=" << x << ", y=" << y << ", z=" << z;
  return 0;
}
x=2, y=6, z=14

Để có quyền truy cập vào các đối số của nó, hàm khai báo các tham số của nó làm tham chiếu. Trong C++, các tham chiếu được biểu thị bằng dấu và () theo kiểu tham số, như trong các tham số được lấy trong ví dụ trên.

Khi một biến được truyền bằng tham chiếu, những gì được truyền không còn là bản sao nữa, mà chính biến, biến được xác định bởi tham số hàm, bằng cách nào đó được liên kết với đối số được truyền đến hàm và bất kỳ sửa đổi nào trên các biến cục bộ tương ứng của chúng trong hàm được phản ánh trong các biến được truyền dưới dạng đối số trong cuộc gọi.

Trên thực tế, , , và trở thành bí danh của các đối số được truyền vào lệnh gọi hàm (, và ) và bất kỳ thay đổi nào trong hàm thực sự là sửa đổi biến bên ngoài hàm. Bất kỳ thay đổi nào về sửa đổi và bất kỳ thay đổi nào về sửa đổi . Đó là lý do tại sao khi, trong ví dụ, hàm sửa đổi các giá trị của biến , và , các giá trị của , , và bị ảnh hưởng.

Nếu thay vì định nghĩa trùng lặp là:&duplicateabcxyzaxbyczduplicateabcxyz

1
void duplicate (int& a, int& b, int& c)

Nó có được định nghĩa mà không có ký hiệu và dấu hiệu là:

1
void duplicate (int a, int b, int c)

Các biến sẽ không được truyền bằng tham chiếu, mà theo giá trị, thay vào đó tạo ra các bản sao của các giá trị của chúng. Trong trường hợp này, đầu ra của chương trình sẽ là các giá trị của , và không bị sửa đổi (tức là 1, 3 và 7).xyz

Cân nhắc hiệu quả và tham chiếu const

Gọi một hàm với các tham số được lấy bởi giá trị sẽ tạo ra các bản sao của các giá trị. Đây là một hoạt động tương đối rẻ tiền đối với các loại cơ bản như , nhưng nếu tham số thuộc loại hợp chất lớn, nó có thể dẫn đến một số chi phí nhất định. Ví dụ: hãy xem xét chức năng sau:int

1
2
3
4
string concatenate (string a, string b)
{
  return a+b;
}

Hàm này lấy hai chuỗi làm tham số (theo giá trị) và trả về kết quả nối chúng. Bằng cách truyền các đối số theo giá trị, hàm buộc và là bản sao của các đối số được truyền đến hàm khi nó được gọi. Và nếu đây là những chuỗi dài, nó có thể có nghĩa là sao chép một lượng lớn dữ liệu chỉ cho cuộc gọi hàm.

Nhưng bản sao này có thể tránh được hoàn toàn nếu cả hai tham số được tạo tham chiếu:ab

1
2
3
4
string concatenate (string& a, string& b)
{
  return a+b;
}

Các đối số bằng cách tham khảo không yêu cầu một bản sao. Hàm hoạt động trực tiếp trên (bí danh của) các chuỗi được truyền dưới dạng đối số và nhiều nhất, nó có thể có nghĩa là chuyển một số con trỏ nhất định sang hàm. Về vấn đề này, phiên bản lấy tham chiếu hiệu quả hơn phiên bản lấy giá trị, vì nó không cần sao chép các chuỗi đắt tiền để sao chép.

Mặt khác, các hàm có tham số tham chiếu thường được coi là các hàm sửa đổi các đối số được truyền, bởi vì đó là lý do tại sao các tham số tham chiếu thực sự dành cho.

Giải pháp là để hàm đảm bảo rằng các tham số tham chiếu của nó sẽ không bị sửa đổi bởi hàm này. Điều này có thể được thực hiện bằng cách đánh giá các tham số là hằng số:concatenate

1
2
3
4
string concatenate (const string& a, const string& b)
{
  return a+b;
}

Bằng cách đủ điều kiện chúng là , hàm bị cấm sửa đổi các giá trị của không cũng không , nhưng thực sự có thể truy cập các giá trị của chúng dưới dạng tham chiếu (bí danh của các đối số) mà không cần phải tạo các bản sao thực tế của chuỗi.

Do đó, các tham chiếu cung cấp chức năng tương tự như truyền các đối số theo giá trị, nhưng với hiệu quả tăng lên cho các tham số của các loại lớn. Đó là lý do tại sao chúng cực kỳ phổ biến trong C ++ cho các đối số của các loại ghép. Tuy nhiên, lưu ý rằng đối với hầu hết các loại cơ bản, không có sự khác biệt đáng chú ý về hiệu quả và trong một số trường hợp, các tham chiếu const thậm chí có thể kém hiệu quả hơn!constabconst

Hàm nội tuyến

Gọi một hàm thường gây ra một chi phí nhất định (xếp chồng các đối số, nhảy, v.v.), và do đó đối với các hàm rất ngắn, có thể hiệu quả hơn khi chỉ cần chèn mã của hàm nơi nó được gọi, thay vì thực hiện quá trình gọi chính thức một hàm.

Trước khi khai báo hàm với mã xác định thông báo cho trình biên dịch rằng mở rộng nội tuyến được ưu tiên hơn cơ chế gọi hàm thông thường cho một hàm cụ thể. Điều này hoàn toàn không thay đổi hành vi của một hàm, mà chỉ được sử dụng để gợi ý trình biên dịch rằng mã được tạo bởi phần thân hàm sẽ được chèn vào mỗi điểm mà hàm được gọi, thay vì được gọi bằng một lệnh gọi hàm thông thường.

Ví dụ: hàm concatenate ở trên có thể được khai báo nội tuyến là:inline

1
2
3
4
inline string concatenate (const string& a, const string& b)
{
  return a+b;
}

Điều này thông báo cho trình biên dịch rằng khi được gọi, chương trình thích hàm được mở rộng nội tuyến, thay vì thực hiện một cuộc gọi thông thường. chỉ được chỉ định trong khai báo hàm, không phải khi nó được gọi.

Lưu ý rằng hầu hết các trình biên dịch đã tối ưu hóa mã để tạo các hàm nội tuyến khi chúng thấy cơ hội cải thiện hiệu quả, ngay cả khi không được đánh dấu rõ ràng bằng mã xác định. Do đó, specifier này chỉ đơn thuần chỉ ra trình biên dịch mà nội tuyến được ưa thích cho hàm này, mặc dù trình biên dịch có thể tự do không nội tuyến nó và tối ưu hóa khác. Trong C++, tối ưu hóa là một tác vụ được giao cho trình biên dịch, miễn phí tạo bất kỳ mã nào miễn là hành vi kết quả là hành vi được chỉ định bởi mã.concatenateinlineinline

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

Trong C++, các hàm cũng có thể có các tham số tùy chọn, trong đó không có đối số nào được yêu cầu trong cuộc gọi, theo cách mà ví dụ, một hàm có ba tham số có thể được gọi chỉ với hai. Đối với điều này, hàm sẽ bao gồm một giá trị mặc định cho tham số cuối cùng của nó, được hàm sử dụng khi được gọi với ít đối số hơn. Chẳng hạn:


// default values in functions
#include <iostream>
using namespace std;

int divide (int a, int b=2)
{
  int r;
  r=a/b;
  return (r);
}

int main ()
{
  cout << divide (12) << '\n';
  cout << divide (20,4) << '\n';
  return 0;
}
6
5

Trong ví dụ này, có hai cuộc gọi để hàm . Trong cái đầu tiên:divide

1
divide (12)

Cuộc gọi chỉ truyền một đối số cho hàm, mặc dù hàm có hai tham số. Trong trường hợp này, hàm giả định tham số thứ hai là 2 (lưu ý định nghĩa hàm, khai báo tham số thứ hai của nó là ). Do đó, kết quả là 6.

Trong cuộc gọi thứ hai:int b=2

1
divide (20,4)

Cuộc gọi chuyển hai đối số cho hàm. Do đó, giá trị mặc định cho () bị bỏ qua và lấy giá trị được truyền làm đối số, nghĩa là 4, mang lại kết quả là 5.bint b=2b

Khai báo hàm

Trong C++, định danh chỉ có thể được sử dụng trong các biểu thức khi chúng đã được khai báo. Ví dụ, một số biến không thể được sử dụng trước khi được khai báo với một câu lệnh, chẳng hạn như:x

1
int x;

Điều tương tự cũng áp dụng cho các chức năng. Các hàm không thể được gọi trước khi chúng được khai báo. Đó là lý do tại sao, trong tất cả các ví dụ về hàm trước đây, các hàm luôn được xác định trước hàm, đó là hàm từ nơi các hàm khác được gọi. Nếu được định nghĩa trước các hàm khác, điều này sẽ phá vỡ quy tắc rằng các hàm phải được khai báo trước khi được sử dụng, và do đó sẽ không biên dịch.

Nguyên mẫu của một hàm có thể được khai báo mà không thực sự định nghĩa hàm hoàn toàn, chỉ cung cấp đủ chi tiết để cho phép các kiểu liên quan đến lệnh gọi hàm được biết đến. Đương nhiên, hàm sẽ được định nghĩa ở một nơi khác, như sau này trong mã. Nhưng ít nhất, một khi tuyên bố như thế này, nó đã có thể được gọi.

Khai báo phải bao gồm tất cả các kiểu liên quan (kiểu trả về và loại đối số của nó), sử dụng cùng cú pháp như được sử dụng trong định nghĩa của hàm, nhưng thay thế phần thân của hàm (khối câu lệnh) bằng dấu chấm phẩy kết thúc.

Danh sách tham số không cần bao gồm tên tham số mà chỉ bao gồm các loại của chúng. Tuy nhiên, tên tham số có thể được chỉ định, nhưng chúng là tùy chọn và không nhất thiết phải khớp với tên trong định nghĩa hàm. Ví dụ, một hàm được gọi với hai tham số int có thể được khai báo với một trong các câu lệnh sau:mainmainprotofunction

1
2
int protofunction (int first, int second);
int protofunction (int, int);

Dù sao, bao gồm tên cho mỗi tham số luôn cải thiện tính dễ đọc của khai báo.


// declaring functions prototypes
#include <iostream>
using namespace std;

void odd (int x);
void even (int x);

int main()
{
  int i;
  do {
    cout << "Please, enter number (0 to exit): ";
    cin >> i;
    odd (i);
  } while (i!=0);
  return 0;
}

void odd (int x)
{
  if ((x%2)!=0) cout << "It is odd.\n";
  else even (x);
}

void even (int x)
{
  if ((x%2)==0) cout << "It is even.\n";
  else odd (x);
}
Please, enter number (0 to exit): 9
It is odd.
Please, enter number (0 to exit): 6
It is even.
Please, enter number (0 to exit): 1030
It is even.
Please, enter number (0 to exit): 0
It is even.

Ví dụ này thực sự không phải là một ví dụ về hiệu quả. Bạn có thể viết cho mình một phiên bản của chương trình này với một nửa dòng mã. Dù sao, ví dụ này minh họa cách các hàm có thể được khai báo trước định nghĩa của nó: Các dòng sau:

1
2
void odd (int a);
void even (int a);

Khai báo nguyên mẫu của các chức năng. Chúng đã chứa tất cả những gì cần thiết để gọi chúng, tên của chúng, các loại đối số của chúng và loại trả về của chúng (trong trường hợp này). Với các khai báo nguyên mẫu này, chúng có thể được gọi trước khi chúng được định nghĩa hoàn toàn, cho phép ví dụ, đặt hàm từ nơi chúng được gọi là () trước định nghĩa thực tế của các hàm này.

Nhưng khai báo các hàm trước khi được định nghĩa không chỉ hữu ích để tổ chức lại thứ tự các hàm trong mã. Trong một số trường hợp, chẳng hạn như trong trường hợp cụ thể này, ít nhất một trong các tuyên bố là bắt buộc, bởi vì và được gọi là lẫn nhau; Có một cuộc gọi đến trong và một cuộc gọi đến trong . Và, do đó, không có cách nào để cấu trúc mã để được xác định trước và trước .voidmainoddevenevenoddoddevenoddevenevenodd

Đệ quy

Đệ quy là thuộc tính mà các hàm phải được gọi bởi chính chúng. Nó rất hữu ích cho một số tác vụ, chẳng hạn như sắp xếp các phần tử hoặc tính toán giai thừa của số. Ví dụ, để có được giai thừa của một số(), công thức toán học sẽ là: Cụ thể hơn, (giai thừa của 5) sẽ là: Và một hàm đệ quy để tính toán điều này trong C++ có thể là:

n!n! = n * (n-1) * (n-2) * (n-3) ... * 15!5! = 5 * 4 * 3 * 2 * 1 = 120


// factorial calculator
#include <iostream>
using namespace std;

long factorial (long a)
{
  if (a > 1)
   return (a * factorial (a-1));
  else
   return 1;
}

int main ()
{
  long number = 9;
  cout << number << "! = " << factorial (number);
  return 0;
}
9! = 362880

Lưu ý cách trong giai thừa hàm, chúng tôi bao gồm một cuộc gọi đến chính nó, nhưng chỉ khi đối số được truyền lớn hơn 1, vì nếu không, hàm sẽ thực hiện một vòng lặp đệ quy vô hạn, trong đó khi nó đến 0, nó sẽ tiếp tục nhân với tất cả các số âm (có thể gây ra tràn ngăn xếp tại một số điểm trong thời gian chạy).

Previous Post

Lập trình hướng đối tượng trong C++

Next Post

Kế thừa và các loại của chúng trong C++

admin

admin

Next Post

Kế thừa và các loại của chúng trong C++

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Trending
  • Comments
  • Latest
cách code hình trái tim bằng c++

Cách code hình trái tim giống với nhân vật Thủ Khoa Lý

December 7, 2023
hướng dẫn cài đặt visual studio code lập trình c++ chi tiết

Cài Đặt Visual Studio Code Lập Trình C++ Chi Tiết Đơn Giản 2024

October 3, 2023
Office 2019 full crack

Cách Crack Office 2019 Đơn Giản, Dễ Hiểu Thành Công 100%

September 19, 2023
Top 10 ứng dụng mua hàng Trung Quốc uy tín nhất hiện nay

Top 10 ứng dụng mua hàng Trung Quốc uy tín nhất hiện nay

January 18, 2025

Các lớp lưu trữ trong cpp

0

Câu lệnh if else trong cpp

0

Chức năng của switch trong cpp

0

Mảng đối tượng trong C++

0
Quick Sort – Thuật toán sắp xếp đột phá trong thế kỉ XX

Quick Sort – Thuật toán sắp xếp đột phá trong thế kỉ XX

October 23, 2023
Top 7 website bán túi xách nữ chính hãng, uy tín nhất

Top 7 website bán túi xách nữ chính hãng, uy tín nhất

October 12, 2023
Hướng dẫn Cài Đặt Và Sử Dụng AutoCAD 2024 Full Crack 

Hướng dẫn Cài Đặt Và Sử Dụng AutoCAD 2024 Full Crack 

October 7, 2023
Hướng Dẫn Tải Và Sử Dụng GS Auto Clicker 3.1.2 Full Crack

Hướng Dẫn Tải Và Sử Dụng GS Auto Clicker 3.1.2 Full Crack

October 5, 2023

Recommended

Quick Sort – Thuật toán sắp xếp đột phá trong thế kỉ XX

Quick Sort – Thuật toán sắp xếp đột phá trong thế kỉ XX

October 23, 2023
Top 7 website bán túi xách nữ chính hãng, uy tín nhất

Top 7 website bán túi xách nữ chính hãng, uy tín nhất

October 12, 2023
Hướng dẫn Cài Đặt Và Sử Dụng AutoCAD 2024 Full Crack 

Hướng dẫn Cài Đặt Và Sử Dụng AutoCAD 2024 Full Crack 

October 7, 2023
Hướng Dẫn Tải Và Sử Dụng GS Auto Clicker 3.1.2 Full Crack

Hướng Dẫn Tải Và Sử Dụng GS Auto Clicker 3.1.2 Full Crack

October 5, 2023
Hướng dẫn học C++

© 2023 Hướng dẫn học C++ - Website thuộc bản quyền của Hướng dẫn học C++.

Liên kết

  • Home
  • Học lập trình
  • Reviews
  • Phần mềm PC
  • App/Ứng dụng
  • Game
  • Hướng dẫn

Theo dõi chúng tôi

No Result
View All Result
  • Home
  • Học lập trình
    • Học C++
  • Reviews
  • Phần mềm PC
  • App/Ứng dụng
  • Game
  • Hướng dẫn
    • PC
    • Mobile Tips

© 2023 Hướng dẫn học C++ - Website thuộc bản quyền của Hướng dẫn học C++.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In