C++ 函数

1、函数的定义与使用

        main函数是C++程序的主函数,主函数是程序执行的起点。由主函数调用子函数,子函数也可以调用子函数。

        调用其他函数的被称为主调函数,被其他函数调用的称为被调函数

1.1 函数的定义

        函数定义的语法:

类型说明符 函数名(含类型说明的形式参数表){
    语句序列
}

        类型说明符规定了函数的返回给主调函数的返回值类型。如果不返回任何值给主调函数,这时可以使用void。当类型说明符不为void时,说明有返回值,返回值需要由return语句给出:

return 表达式;//有返回值时一定含有return语句

return;//没有返回值可以这样写,也可以不写

        函数下形参表可以为空,表示没有任何形参。如main()函数就可以没有形参。main也可以有形参,这时比较特殊,main函数的形参也叫命令行参数,由操作系统在启动程序时初始化。

1.2 函数的调用

1.2.1 函数调用形式

        调用函数之前首先要定义函数,但如果希望在定义一个函数前调用它,则需要在调用函数之前添加该函数的函数原型声明。

        函数原型声明只是将有关函数的有关信息告诉了编译器,此时不产生任何代码。

        如果在所有函数之前声明了函数原型,那么该函数在本程序文件中任何地方都可以调用。如果只是在某个主调函数内部声明了被调函数原型,那么该原型只能在这个函数内部有效

        函数原型声明的形式如下:

类型说明符 函数名(含类型说明的形参表)
//!!函数原型声明的时候形参表的形参名可以省略,只包含类型信息即可,但不推荐

        声明了函数原型之后就可以调用函数了:

函数名(实参列表)

1.2.2 嵌套调用、递归调用

        嵌套调用:如果函数1调用了函数2,就形成了嵌套调用。

        递归调用:函数可以直接或间接地调用自身,称为递归调用

1.3 函数的参数传递

        函数的参数传递指定就是形参核实参的结合(形实结合),形实结合的方式有值传递引用传递

  • 实参指的是调用函数时放在参数列表的变量
  • 形参指定是在函数体内部使用的参数列表的变量

1.3.1 值传递

        值传递是指当发生函数调用时,给形参分配内存空间,并用实参来初始化形参(直接将实参的值传递给形参)。形参获得了值之后就与实参脱离了关系,此后形参发生什么样的变化都不会影响到实参。

1.3.2 引用传递

        引用传递可以解决值传递中的问题——形参无法对实参产生影响。

        引用是一种特殊类型的变量,可以被认为是另一个变量的别名,通过引用名与通过被引用的变量名访问变量的效果是一样的。

2、内联函数的声明与使用

2.1 什么是内联函数

        意指:当编译器发现某段代码在调用一个内联函数时,它不是去调用该函数,而是将该函数的代码,整段插入到当前位置。这样做的好处是省去了调用的过程,加快程序运行速度。

  • 声明时使用关键帧inline。
  • 编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销。
  • 本质上就是空间换时间

2.2 内联函数定义

        只要在函数声明或定义前加一个 inline 修饰符。 
inline int max(int a, int b) 

   return (a>b)? a : b; 
}

2.3 内联函数注意事项

  1. 含有递归调用的函数不能设置为inline
  2. 内联函数体不能有循环语句、switch语句
  3. 内联函数增加体积的特性,所以建议inline函数内的代码有关很短小,最好几行内搞定。
  4. 内联函数的声明必须出现在内联函数第一次被调用之前
  5. 对内联函数不能进行异常接口声明

2.4 内联函数和宏定义函数的区别

  1. 内联函数是在编译的时候展开的,宏是在预编译时展开;在编译时,内联函数直接被嵌入到目标代码中去,而宏只是有关简单的文本替换。
  2. 内联函数可以进行类型安全检查、语句是否正确等编译功能,宏不具有这样的功能;宏不是函数,inline是函数。
  3. 内联函数在运行时可以运行,宏定义不行。
  4. 内联函数可以访问类的成员变量,宏不可用。

3、带默认形参的函数

        3.1、作用:

        函数在声明时可以预先给出默认的形参值,调用时如给出实参,则采用实参值,否则采用预先给出的默认形参值。

int add(int x=5,int y=6)
{
    return  x+y;
}

       3.2、次序:

         默认形参值必须从右向左顺序声明,并且在默认形参值的右面不能有非默认形参值的参数。因为调用时实参取代形参是从左向右的顺序。

int add(int x,int y=5,int z=6); //正确
int add(int x=1,int y=5,int z); //错误
int add(int x=1,int y,int z=6); //错误

        3.3、调用位置:

        调用出现在函数体实现之前时,默认形参值必须在函数原形中给出;而当调用出现在函数体实现之后时,默认形参值需在函数实现时给出。

int add(int x=5,int y=6);//提前声明函数原型的话要加默认值
void main(void)
{   add(); //调用在实现前
}
int add(int x,int y)
{   return x+y;   }



int add(int x=5,int y=6)
{   return  x+y;   }
void main(void)
{   add();   //调用在实现后
}

        4、默认形参的作用域

        在相同的作用域内,默认形参值的说明应保持唯一,但如果在不同的作用域内,允许说明不同的默认形参。

int add(int x=1,int y=2);
Int z=10;
void main(void)
{ int z=5;
 int add(int x=3,int y=4);
    add();  //使用局部默认形参值(实现3+4)
}
void fun(void)
{   ...
     add();  //使用全局默认形参值(实现1+2)
}

4、函数重载

        C++允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载。方便使用,便于记忆。

         重载函数的形参必须不同: 个数不同或类型不同。

//形参类型不同
int add(int x, int y);
float add(float x, float y);

//形参个数不同
int add(int x, int y);
int add(int x, int y, int z);

        下面是一些错误的情况

//编译器不以形参名来区分。函数重载是在编译阶段,但如果用形参来区分需要在运行的阶段,所以不行。
int add(int x,int y);
int add(int a,int b);

//编译器不以返回值来区分
int add(int x,int y);
void add(int x,int y);

        不要将不同功能的函数声明为重载函数,以免出现调用结果的误解、混淆。这样不好:

5、函数指针和指针函数

5.1 函数指针

        在程序运行中,函数代码是程序的算法指令部分,它们和数组一样也占用存储空间,都有相应的地址。可以使用指针变量指向函数代码的首地址,指向函数代码首地址的指针变量称为函数指针。

int* func(int x);   // 声明一个函数 
int* (*f) (int x); // 声明一个函数指针 ,返回值为int*,形参只有一个int 
f=func;            // 将func函数的首地址赋给指针f 

5.2 指针函数

        一个函数不仅可以带回一个整型数据的值,字符类型值和实型类型的值,还可以带回指针类型的数据,使其指向某个地址单元。 

(int *)  f(x,y);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

buzhengli

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

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

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

打赏作者

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

抵扣说明:

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

余额充值