C++青少年简明教程:C++函数

种地  论坛元老 | 2024-6-22 12:57:46 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1084|帖子 1084|积分 3252

C++青少年简明教程:C++函数


C++函数是一段可重复利用的代码,用于执行特定的任务,可以进步代码的可读性和可维护性。函数可以接受参数(输入)并返回一个值(输出),也可以没有参数和返回值。
按函数是否由系统界说:分为库函数(系统函数)和自界说函数。
C++ 尺度库提供了大量的步伐可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。
本文重点介绍自界说函数。

函数界说(Function Definition)格式
<返回范例> <函数名>(<参数列表>)
{
     函数体,执行具体的利用
}
函数界说包罗函数的返回范例、名称、参数列表和函数体。
参数列表包罗函数接受的参数的范例和名称。可以有零个或多个参数,每个参数由范例和名称构成,并用逗号分隔。
对于C++,main 函数(是步伐的入口点)的范例必须是 int。对于自界说函数,函数范例可以是任何范例,包罗 void(体现没有返回值)和其他根本数据范例(如 int、float 等等)。如果函数有返回值,则必须在函数体中利用 return 语句返回相应范例的值。在函数体中利用 return 语句时会将步伐的执行控制权返回到调用该函数的地方,接着执行调用该函数的语句背面的代码。对于void范例的自界说函数,可以省略 return 语句大概利用“ return;”语句显式地体现函数的结束。
在C++中,函数声明(函数原型声明)是指在利用函数之前提供函数原型的过程。它包罗函数的名称、参数列表和返回范例的形貌,用于告诉编译器如何调用该函数。当函数的实现位于调用它的代码之后时,你需要提前声明这个函数,告诉编译器这个函数存在。C++函数头文件通常包罗函数声明,以便在其他文件中引用和利用这些函数。
函数声明的一样平常形式为:
返回范例 函数名(参数列表);
例如:
int add(int a, int b); // 声明一个名为 add 的函数,它接受两个 int 范例的参数并返回一个 int 范例的值
【在C++中,用关键字extern可以进行函数声明,但这不是必须的,例如,“extern int add(int a, int b);”。在C++中,如果没有函数体的函数声明,通常都被认为是extern的。
对于函数声明,可以省略参数名,只生存参数范例。所以int js(int n);和int js(int);是等价的。】
函数声明和函数的界说在形式上的区别函数声明没有函数体。函数界说:
int add(int a, int b) {
    return a + b; // 实现 add 函数,返回两个参数的和
}
函数声明是指提供函数原型的过程,用于告诉编译器有一个函数的存在和根本信息;而函数界说是给出函数具体实现的过程,包罗函数头和函数体,用于形貌函数的行为和实现。

函数调用(Function Call):
当你想在步伐中利用函数时,你会"调用"它。调用函数时,你需要提供须要的参数(如果有的话)——实参。例如:
add(5, 3);

函数的形参和实参
函数的形参(形式参数)是在函数界说中声明的参数,它们用来接受函数调用时通报的实参值。形参在函数执行时起到的是占位符的作用,它们的值在函数调用时由相应的实参通报进来。
函数的实参(现实参数)是在函数调用中通报给函数的值或变量。实参可以是常量、变量、表达式、函数返回值等。当函数被调用时,实参的值被通报给形参,函数将利用这些值进行运算或处置惩罚,并可能返回一个结果。
例子:
  1. #include <iostream>
  2. using namespace std;
  3. // 函数声明
  4. int add(int a, int b);
  5. int main() {
  6.     int x = 5;
  7.     int y = 10;
  8.     int sum = add(x, y); //函数调用 ,x 和 y 是实参,它们的值被传递给 add 函数的形参 a 和 b
  9.     cout << "和: " << sum << endl;
  10.    
  11.     return 0;
  12. }
  13. // 函数定义
  14. int add(int a, int b) {
  15.     return a + b;
  16. }
复制代码
运行结果:


函数声明(Function Declaration)和函数界说(Function Definition)是两个差别的概念。
函数声明告诉编译器函数的名称、返回范例以及它接受哪些参数。但它不包罗函数的现实代码。函数声明通常出现在函数被调用之前,以便编译器知道函数的存在和它的签名(即它的参数和返回范例)。
函数界说提供了函数的现实代码,即函数体。它包罗了函数如何执行其任务的详细信息。函数界说也可以被视为函数的完整签名加上函数体。
函数界说中的函数名、返回范例以及参数列表必须与相应的函数声明完全匹配(除了某些特别情况,如内联函数或模板函数)
在大型步伐中,通常将函数声明放在头文件中,而函数界说放在源文件中。这样,其他源文件可以通过包罗相应的头文件来利用该函数。
函数调用(Function Call)是执行已界说函数的方式。函数调用时,步伐将控制权交给函数,并在函数执行完毕后返回。函数调用作为语句、表达式和参数的利用示例:
  1. #include <iostream>
  2. using namespace std;
  3. int add(int a, int b) {
  4.     return a + b;
  5. }
  6. void printMessage() {
  7.     cout << "Hello, World!" << endl;
  8. }
  9. void displayResult(int result) {
  10.     cout << "Result: " << result << endl;
  11. }
  12. int main() {
  13.     printMessage();  // 作为语句
  14.     int sum = add(5, 3);  // 作为表达式的一部分
  15.     displayResult(sum);   // 作为参数传递
  16.     displayResult(add(2, 2));  // 嵌套使用:作为参数传递时作为表达式的一部分
  17.     return 0;
  18. }
复制代码
输出结果:
Hello, World!
Result: 8
Result: 4

C++函数参数的通报方式
函数参数通报是指在函数调用时,将现实参数(也称为实参)的值或引用通报给函数的形式参数(也称为形参)的过程。在C++中,当调用一个函数时,你需要提供与函数声明中指定的形参范例和数量相匹配的实参。这些实参可以是变量、常量、表达式或字面值等。
当调用函数时,通报参数的方式有:
1. 值通报(Pass by Value)/传值
将实参的值复制一份传给形参,在函数内对形参进行利用,不会影响到实参。在这种情况下,修改函数内的形式参数对现实参数没有影响。
  1. #include <iostream>
  2. using namespace std;
  3. void add(int a, int b) {
  4.     cout << "a + b = " << a + b << endl;  
  5. }
  6. int main() {
  7.     int x = 5, y = 10;
  8.     add(x, y); // 值传递方式调用函数
  9.     return 0;
  10. }
复制代码
2. 引用通报(Pass by Reference)/传地址
将实参的地址通报给形参,在函数内对形参进行利用,就是直接对实参利用。这意味着,修改形式参数会影响现实参数。
  1. #include <iostream>
  2. using namespace std;
  3. void increment(int &num) {
  4.     num++; // 修改 num 的值
  5. }
  6. int main() {
  7.     int a = 5;
  8.     increment(a); // 引用传递方式调用函数
  9.     cout << "a = " << a << endl; // 输出 a 的值
  10.     return 0;
  11. }
复制代码
需要注意的是,在利用引用通报方式时,要确保通报的实参是一个变量而非常量或表达式的值。例如,以下代码是无效的:
increment(2 + 3); // 无法编译通过,因为2 + 3不是一个变量

3. 指针通报(Pass by Pointer)/传指针
指针通报(Pass by Pointer)通过通报指向实参的指针,让函数可以或许访问和修改实参的值。这意味着,修改形式参数会影响现实参数。关于指针以后介绍。
  1. #include <iostream>
  2. using namespace std;
  3. void increment(int* ptr) {
  4.     (*ptr)++; // 修改 *ptr 所指向的变量的值
  5. }
  6. int main() {
  7.     int a = 5;
  8.     int* ptr = &a;
  9.     increment(ptr); // 通过指针传递实参
  10.     cout << "a = " << a << endl; // 输出 a 的值
  11.     return 0;
  12. }
复制代码
在 increment 函数中,通过解引用运算符 (*ptr) 访问了实参 a 的值,并对其进行了修改。在 main 函数中,界说了整型变量 a 和指向 a 的指针 ptr,将 ptr 作为参数通过指针通报给了 increment 函数。最后输出了 a 的值,结果为 6。

提示:引用通报和指针通报都是将实参的地址通报给形参。差别的是,引用通报利用了引用范例,而指针通报利用了指针范例。在函数内部,引用和指针都可以用于访问和修改实参的值。具体一点说,通过引用通报,函数形参会成为实参的别名,即形参与实参指向同一块内存空间,在函数内部对形参的修改会直接反映在实参上。通过指针通报,现实参数的地址被复制到指针形参中,通过解引用指针可以访问和修改实参的值。
在大多数情况下,引用通报比值通报需要更少的内存,并更有用。通报指针也是一种通报地址的方式,但是引用更容易利用,并且更不容易堕落。

函数参数的默认值
在C++编程中,在界说函数时,可以为函数参数设置默认值。如果在调用函数时未通报参数,则利用默认值。例如:
  1. #include <iostream>
  2. using namespace std;
  3. int sum(int a, int b = 6 ){
  4.     return ( a + b );
  5. }
  6. int main (){
  7.     // 局部变量声明
  8.     int a = 10;
  9.     int b = 20;
  10.     int result;
  11.     // 调用函数计算和
  12.     result = sum(a, b);
  13.     cout << "sum = " << result << endl; //sum = 30
  14.     // 再次调用函数
  15.     result = sum(a);
  16.     cout << "sum = " << result << endl; //sum = 16
  17.     return 0;
  18. }
复制代码

C++变量的作用域
C++中变量的作用域是指变量在步伐中可以或许被访问到的范围。按变量的作用域可以将变量分为:
局部变量:变量在某个函数内部界说,只能在该函数内部访问,称为局部变量。
下面是利用了局部变量的例子:
  1. #include <iostream>
  2. using namespace std;
  3. int main (){
  4.   // 局部变量声明
  5.   int a, b;
  6.   int c;
  7.   // 实际初始化
  8.   a = 10;
  9.   b = 20;
  10.   c = a + b;
  11.   cout << c;
  12.   return 0;
  13. }
复制代码
全局变量:在全部函数外部界说的变量(通常是在步伐的头部),称为全局变量。全局变量一旦声明,在整个步伐中都是可用的。
下面是利用了全局变量的例子:
  1. #include <iostream>
  2. using namespace std;
  3. //全局变量
  4. int x = 20;
  5. void func(){
  6.     int x = 10;  //函数内部的局部变量
  7.     cout << "局部变量 x 的值为 : " << x << endl;  //输出 10
  8.     cout << "全局变量 x 的值为 : " << ::x << endl;  //输出 20
  9. }
  10. int main(){
  11.     cout << "初始全局变量 x 的值为 : " << x << endl;  //输出 20
  12.     func();  //调用函数
  13.     cout << "调用函数后的全局变量 x 的值为 : " << x << endl;  //输出 20
  14.    
  15. return 0;
  16. }
复制代码
示例中,界说了一个全局变量 x,它的值为 20。然后,在 func() 函数内界说了一个名称相同的局部变量 x,它的值为 10。当 func() 函数被调用时,它将输出局部变量 x 和全局变量 x 的值。从输出可以看出,步伐优先利用函数内部的局部变量 x,而不是全局变量 x。如果需要利用或修改全局变量的值,则需要在函数中利用作用域解析运算符 :: 来引用全局变量。
在主函数中,我们首先输出全局变量 x 的值,然后调用函数 func()。在调用函数之后,我们再次输出全局变量 x 的值,以此证明函数内部对全局变量的修改并不会影响它的值。从输出可以看出,函数 func() 对全局变量 x 的修改并没有影响它的值,它的值仍旧是 20。

训练、判定一个年份是否为闰年是一个常见的编程问题。闰年的规则是:
如果年份能被4整除但不能被100整除,则为闰年。
如果年份能被400整除,也是闰年。
以前(“If选择语句”一节中)提到过这个例子,现在接纳自界说函数的方式实现,判定用户输入的年份是否为闰年:
  1. #include <iostream>  
  2. using namespace std;
  3.   
  4. bool isLeapYear(int year) {  
  5.     if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {  
  6.         return true;  
  7.     } else {  
  8.         return false;  
  9.     }  
  10. }  
  11.   
  12. int main() {  
  13.     int year;  
  14.     cout << "请输入一个年份: ";  
  15.     cin >> year;  
  16.   
  17.     if (isLeapYear(year)) {  
  18.         cout << year << " 是闰年." << endl;  
  19.     } else {  
  20.         cout << year << " 不是闰年." << endl;  
  21.     }  
  22.   
  23.     return 0;  
  24. }
复制代码
这个步伐中,isLeapYear 函数接受一个整数年份作为参数,并返回一个布尔值,体现该年份是否为闰年。main 函数则负责获取用户输入的年份,并调用 isLeapYear 函数进行判定,然后输出相应的结果。

递归函数
在编程中,一个函数直接或间接地调用自身,函数称为递归函数,这种技术被称为递归。
递归函数通常包罗两个部分:
根本情况(Base Case):这是递归的停止条件,即当函数达到某个条件时,它将不再调用自身,而是直接返回结果。没有根本情况,递归函数将会无穷地调用自身,导致栈溢堕落误。
递归步骤(Recursive Step):这是函数的主体部分,此中包罗了将问题分解为更小子问题的逻辑,并调用自身(称为Recursive call:递归调用)来处置惩罚这些子问题。

简单地说,递归是一种函数调用自身的过程。递归函数或算法必须调用自身来办理规模更小的子问题。

我们可以利用一个例子来阐明。好比,我们要盘算从1到某个数n的总和。
1.我们可以创建一个自界说函数sum,它接受一个参数n,代表要盘算总和的范围。
2.在函数内部,我们需要添加一些根本条件来结束递归。在这种情况下,如果n等于1,我们直接返回1。
3.如果n大于1,我们将函数自己调用,并传入n-1作为参数,并将结果与n相加。
4.这个过程会不停进行下去,直到n等于1,然后每个递归函数的返回值都会被加起来。
最后,我们只需调用这个函数并打印出结果即可。
  1. #include <iostream>
  2. using namespace std;
  3. int sum(int n) {
  4.     if (n == 1) {
  5.         return 1;
  6.     }
  7.     else {
  8.         return n + sum(n - 1);
  9.     }
  10. }
  11. int main() {
  12.     int num = 5;  // 假设我们要计算1到5的总和
  13.     int result = sum(num);
  14.     cout << "从1到" << num << "的总和为:" << result << endl;
  15.     return 0;
  16. }
复制代码

盘算阶乘
阶乘(Factorial)是指将一个正整数 n 及小于等于 n 的全部正整数相乘的结果。符号通常用符号 "!" 体现。例如,4的阶乘(写作4!)是4*3*2*1=24。
C++函数来盘算阶乘的函数:
int factorial(int n) {
    if (n == 0) {
        return 1;
    } else {
        return n * factorial(n - 1);
    }
}
这个函数的工作方式是这样的:
首先,它检查数字n是否为0。如果是,它返回1。这是因为0的阶乘被界说为1。
如果n不是0,那么函数会返回n乘以n-1的阶乘。这就是递归的部分:函数调用了自己,但是每次调用时,n都会减少1。
例如,如果我们调用factorial(4),函数会这样工作:
factorial(4)返回4 * factorial(3)
factorial(3)返回3 * factorial(2)
factorial(2)返回2 * factorial(1)
factorial(1)返回1 * factorial(0)
factorial(0)返回1
所以,factorial(3)的结果是4*3 * 2 * 1 * 1 = 24。
图示如下:


下面给出求一个数的阶乘完整代码
利用递归的完整代码:
  1. #include <iostream>
  2. using namespace std;
  3. int factorial(int n) {
  4.     if (n == 0) {
  5.         return 1;
  6.     } else {
  7.         return n * factorial(n - 1);
  8.     }
  9. }
  10. int main() {
  11.     int n;
  12.     cout << "请输入一个正整数: ";
  13.     cin >> n;
  14.     cout << "该数的阶乘为: " << factorial(n) << endl;
  15.     return 0;
  16. }
复制代码
这个递归示例中,函数名为 factorial,体现盘算一个数的阶乘。当输入的参数 n 等于 0 时,是递归的根本情况,递归将结束并返回 1。当 n 不是 0 时,函数将调用自身并传入 n-1 作为参数,直到 n 等于 0。然后递归将回溯,并将每个递归调用返回的值合并,并返回给原始调用者。

作为对比,下面给出非递归实现的代码:
  1. #include <iostream>
  2. using namespace std;
  3. int factorial(int n) {
  4.     int result = 1;
  5.     for (int i = 1; i <= n; i++) {
  6.         result *= i;
  7.     }
  8.     return result;
  9. }
  10. int main() {
  11.     int n;
  12.     cout << "请输入一个正整数: ";
  13.     cin >> n;
  14.     cout << "该数的阶乘为: " << factorial(n) << endl;
  15.     return 0;
  16. }
复制代码
OK!
附、C++函数https://blog.csdn.net/cnds123/article/details/108917528


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表