一文带你搞清C++函数

函数的声明和定义

前面我们的代码都比较简单,内容也比较少,我们把代码全部放在了main函数里面。

如果在一个复杂的程序中,如果我们把所有的代码都放到main函数里面就会显得特别臃肿庞大,杂乱无章。现在有一种方法就是分块,把一些代码拿出去,把仍无分工到其他的函数中,main函数值负责核心的程序流程,具体的任务由其它函数完成。

这种思想就是模块化编程。

声明和定义函数的语法:

返回值的数据类型 函数名(参数一的数据类型 参数一, 参数二的数据类型 参数二,……)

{

    实现函数功能的代码。

    return 返回值;

}

函数的声明:让编译器知道函数的存在,包括返回值的数据类型、函数名和参数列表。

因为我们不一定函数定义会在main函数前面,前面我们提到了main函数时最开始执行的,在编译过程中,是会从代码最前面找,先找对应的头文件进行编译获取,直到找到main函数,这是程序才开始跑,如果函数的定义在main函数的后面,但是并未声明,我们在main函数中调用就会发现报错了,因为main函数没找到,所以我们需要在main函数前面进行声明,以后,为了防止没有声明的问题,不管函数写在main函数前面还是后面,我们统一在main函数前面进行声明。

函数的定义:函数的实现过程。

注意:

  1.  函数的声明和定义可以书写在一起,也可以分开,如果书写在一起,一般放在main函数的上面,如果分开,一般在main函数的上面声明,在main函数的下面定义。
  2. 如果函数的声明和定义分开书写,函数的声明后面一定要有分号,函数的定义后面一定不能写分号。
  3. 在同一个程序中,函数只需要声明和定义一次,也可以多次声明,但只能定义一次。
  4. 函数的声明必须和函数的定义一致(返回值的数据类型、函数名和参数列表),如果函数名和参数列表不同,表示它们不是同一个函数。
  5. return语句返回值的数据类型必须与函数的声明一致。
  6. 在函数体中,return语句可以多次使用。
  7. 如果函数的重点是实现功能,不关心返回值,返回值的数据类型填void,return语句后面就空着。
  8. 函数可以没有任何参数。
  9. 函数名是标识符,必须满足标识符的命名规则。
  10. 在函数的声明和函数的定义中,参数命名可以不同,但是没必要这么书写。

示例:

#include <iostream>         // 包含头文件。

using namespace std;    // 指定缺省的命名空间。

/*
    这里是函数声明部分
*/

// 写一个函数,给它两个整数,让它比较两个整数的大小,返回较大的那个整数。

int max(int a, int b);  //函数声明后面的分号不能少。


// 写一个函数,给它一个字符串,让它在控制台显示出来。

void print(string str);


// 写一个函数,在控制台输出九九乘法表。

void printn();



int main()
{
    int a = 0, b = 0, Max = 0;
    Max = max(a, b);    //用Max接收比较后返回的的值

    cout << Max << endl;

    print("xigou");

    printn();

    return 0;

}



int max(int a, int b)       // 函数定义后面不能加分号。
{
    //a>b ? a : b;  三目运算符替换
    if (a > b) return a;
    return b;
}



void print(string str)
{
    cout << str << endl;
    return;
}



void printn()
{
    // 在控制台输出九九乘法表。
    for (int ii = 1; ii <= 9; ii++)
    {
        for (int jj = 1; jj <= ii; jj++)
        {
            cout << ii << "*" << jj << "=" << ii * jj << " ";
        }
        cout << endl;
    }
    return;
}


 函数的调用

语法:函数名(参数一,参数二,……)

注意:

  • 声明函数的代码必须放在调用之前,定义函数的代码可以放在调用之后。
  • 调用函数的时候,参数列表必须与函数的声明一致(参数的个数、书写的顺序和数据类型)。
  • 不管在什么地方,都不能调用main函数,但是,在普通函数中,可以调用其它的普通函数。
  • 调用函数的代码可以独占一条语句,也可以用于表达式(赋值运算、算术运算、关系运算、函数的参数)。
  • 如果函数用于表达式中,返回值的数据类型要匹配(否则可能会被隐式转换或编译错误)。
  • 如果函数有返回值,可以不关心它,忽略它。

代码示例在前面示例中。


 变量的作用域

用域是程序中变量存在(或生效)的区域,超过该区域变量就不能被访问。

变量分全局变量和局部变量两种,全局变量在整个程序中都可以访问,局部变量只能在函数或语句块的内部才能访问。

C++中定义变量的场景主要有五种:    

        1)在全部函数外面定义的是全局变量

        2)在头文件中定义的是全局变量。

        3)在函数和语句块内部定义的是局部变量

        4)函数参数是该函数的局部变量

        5)函数内部用static修饰的是静态局部变量。

1)全局变量

        在整个程序生命周期内都是有效的,在定义位置之后的任意函数中都能访问。

        全局变量在主程序退出时由系统收回内存空间。

2)局部变量

        在函数或语句块内部的语句使用在函数或语句块外部是不可用的

        局部变量在函数返回或语句块结束时由系统收回内存空间。

3)静态局部变量

        用static修饰的部变量生命周期和程序相同,并且会被初始化一次

        其作用域为局部,当定义它的函数或语句块结束时,其作用域随之结束。

        当程序想要使用全局变量的时候应该先考虑使用static(考虑到数据安全性

4)注意事项

  • 全局变量和静态局部变量自动初始化为0。
  • 局部变量不会自动初始化,其值是不确定的,程序中应该有初始化局部变量的代码,否则编译可能会报错(不同的编译器不一样)。
  • 局部变量和全局变量的名称可以相同,在某函数或语句块,如果局部变量名与全局变量名相同,就屏蔽全局变量而使用局部变量,如果想使用全局变量,可以在变量名前加两个冒号(::)。
  • for循环初始化语句中定义的变量的作用域是for语句块。

static修饰的局部变量示例:

#include<iostream>
using namespace std;


void func();
int main()
{
    func();
    func();
    func();
}

void func()
{
    int a = 10;
    static int b = 10;
    cout << "func a = " << a++ << endl;
    cout << "func b = " << b++ << endl;
}

 函数参数的传递

调用函数的时候,调用者把数值赋给了函数的参数。

实参:调用者程序中书写的在函数名括号中的参数,可以是常量、变量和表达式。

形参:函数的参数列表。

在函数定义的代码中,修改形参的值,会不会影响实参。

示例:

#include <iostream>         // 包含头文件。

using namespace std;    // 指定缺省的命名空间。

/*
    这里是函数声明部分
*/

// 写一个函数,给它两个整数,让它比较两个整数的大小,返回较大的那个整数。

int max(int a, int b);  //函数声明后面的分号不能少。


// 写一个函数,给它一个字符串,让它在控制台显示出来。

void print(string str);





int main()
{
    int a = 0, b = 0, Max = 0;
    Max = max(a, b);    //用Max接收比较后返回的的值

    cout << Max << endl;

    print("xigou");


    return 0;

}



int max(int a, int b)       // 函数定义后面不能加分号。
{
    //a>b ? a : b;  三目运算符替换
    if (a > b) return a;
    return b;
}



void print(string str)
{
    cout << str << endl;
    return;
}



 函数分文件编写

头文件(*.h:需要包含的头文件,声明全局变量,函数的声明,数据结构和类的声明等。

源文件(*.cpp:函数的定义、类的定义。

主程序:main函数,程序的核心流程,需要用#include "头文件名"把头文件包含进来。

编译:

Windows是集成开发环境,不需要写编译指令。

/*demo01.cpp*/
#include "tools.h"         // 包含头文件tools.h,min和max函数在里面。
#include "demo1.h"          // 包含头文件demo1.h,print函数在里面。

int main()
{
	cout << "max(5,8)=" << max(5, 8) << endl;
	cout << "min(5,8)=" << min(5, 8) << endl;
	print("我是。。。");
}
/*demo1.cpp*/
#include "demo1.h"

void print(string str)   
{
	cout<<str<<endl;
}
/*tools.cpp*/
#include "tools.h"

int max(int a, int b)    // 比较两个数的大小,返回较大者。
{
	return a > b ? a : b;
}

int min(int a, int b)    // 比较两个数的大小,返回较小者。
{
	return a < b ? a : b;
}
/*demo1.h*/
#pragma once                //防止头文件被从重复包含

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

void print(string str);   

注意:#program once是指头文件只被include包含一次

那么为什么不能从包含呢?

        因为如果这个文件里面有定义变量或者说开辟空间的操作的话,可能会导致开辟两次 同一个标记名的空间,会报错,不知道这么说好不好理解。

/*tools.h*/
#pragma once                //防止头文件被重复包含。

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

int max(int a, int b);    // 比较两个数的大小,返回较大者。
int min(int a, int b);    // 比较两个数的大小,返回较小者。

递归函数 

        一个函数可以调用另一个函数,作为特例,如果函数调用了自己,就像故事中提到了同样的故事一样,我们把函数在运行时调用自己的情况叫做递归。

        递归函数中一定要有递归终止的条件,否则是死递归。死递归会导致内存占用太多,所以不太建议大家刚开始学就用,可以转换为循环使用。

示例:

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

int f(int x)                            // 递归函数。
{
    if (x == 0) return 0;        // 递归终止的条件。

    return x + f(x - 1);          // 在函数体中调用了自己。
}

int main()
{
    cout << "f(100)=" << f(100) << endl;
    // 100+99+98+....+1+0          
    // 嵌套的调用函数  进入函数的过程是递去  函数返回的过程是归来

    // 计算从1加到100的和。
    int sum = 0;         //  存放累加的值。
    for (int ii = 1; ii <= 100; ii++)
        sum = sum + ii;

    cout << "sum=" << sum << endl;
}

 以上便是此次博客分享的内容啦,如果有错误的地方请兄弟们评论指出嗷!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸福西西弗斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值