6.函数

C++

Posted by HustDsy on September 6, 2020

函数是一个命名了的代码块,可以有0个或多个参数。通常只产生一个结果,允许重载函数,也就意味着同一个名字可以对应多个不同给的函数。

6.1函数基础

void f1(){} //隐式的表示f1没有形参
void f1(void){}//显示的表示f1没有形参

实参是是形参的初始值

6.1.1局部对象

  • 名字的作用域指的是程序文本的一部分,名字在其中可见
  • 对象生命周期是程序执行过程中该对象存在的一段时间

局部变量:形参和函数内部定义的变量统一称为局部变量。

自动对象:对于普通局部变量对应的对象来说,函数经过变量定义语句时,创建该对象,到达定义所在的块末尾的时候销毁它。我们把只 存在于块执行期间的对象称为自动对象。

局部静态对象:在定义局部变量的前面增加关键字static即可。局部静态对象在程序的执行路径第一次经过对象定义的语句时初始化,直 到程序终止的时候才销毁。

int counter(){
    static int num=0;//局部静态对象
    return ++num;
}
int call(){
    int num=0; //普通的局部变量
    return ++num;
}
int main(){
    for(int i=0;i<10;i++){
        cout<<counter()<<call()<<endl;
    }
    return 0;
}

counter输出的是1-10,而call函数输出的是10个1

6.1.2函数声明

函数的三要素分别是返回类型,函数名,形参类型,返回值。一般要在头文件进行函数的声明,在源文件进行定义。

#ifndef chapter6_hpp
#define chapter6_hpp
#include <stdio.h>
#include<iostream>
using namespace std;

int kk(int b);//声明 kk函数

#endi
#include "chapter6.hpp"
//实现kk函数
int kk(int b){
    return b;
}

6.2参数传递

  • 当形参是引用类型的时候,我们说它对应的实参被引用传递。和其它引用一样,引用形参现在是它绑定对象的别名。
  • 当实参的值被拷贝给形参的时候,形参和实参是两个独立的对象,我们说这样的实参被值传递。也就是将实参的值拷贝一份后赋值给形参。
//值传递
int test(int b){
    return b-1;
}
//引用传递
int test1(int&c){
    c--;
    return c;
}
//输出结果b还是1,c是0
int main(){
    int b=1;
    int c=1;
    test(b);
    test1(c);
    cout<<b<<c<<endl;
    return 0;
}

使用引用避免拷贝,拷贝大的类类型或者容器对象比较低效并且有的类型不支持拷贝构造可以传引用参数(如果函数无需改变形参的值,最好将其声明为引用传递

bool isShorter(const string&s1,const string&s2){
    return s1.length()<s2.length();
}

6.3返回类型和return语句

不要反回局部对象的引用或者指针

const string& getString(){
    string aa="111";
    retrun aa; //错误的,返回了一个局部对象
}

返回数组指针

int arry[10];//arry是包含10个整数的数组
int *p1[10];//p1是一个含有10个指针的数组
int (*p1)[10]=&arry;//p1是一个指针,指向一个包含10个整数的数组,这里把(*p1)理解成(arry)就好了
int (*func(int i))[10];//声明一个返回数组指针的函数,相当于它指向数组的首地址 
int * func(int x);//这个的话 直接返回数组的首地址

6.4函数重载

重载函数形参个数或者类型不同

重载和const形参

//const为顶层的,两个函数等价,这样子重载错误
int A(int *B);
int A(int *const B);
//const为底层的,两个函数不等价,这样子重载正确
int B(int *B);
int B(const int*B);

const_cast类型转换,将const转为常量

比如返回长度最小的字符串 isShorter如上

string& getShorterString(string &s1,string &s2){
    const string &r=isShorter(const_cast<const string&>(s1),const_cast<const string&>(s2);
    return const_cast<string&>(r);
}

6.5特殊用途语言特性

  • 默认实参 int A(int a=0,int b=1,int c=1),前面被赋予默认实参的话,那么后面也要,a被赋了默认形参的话,那么b,c一定要被赋予
  • inline函数,调用函数一般比求等价的表达式要慢一点,加入inline关键字,变成内联函数的话,那么这个函数的执行相当于等价表达式,比如isShorter函数。里面就执行了一个比较函数,但是为了美观,我们把它封装成了一个函数。

6.6函数指针

int A(int a,int b);
int (*P)(int a,int b);
//p=A或者p&A都是正确的;
p=A;
//调用的时候
int c=p(1,2);
//等价于A(1,2)