C++学习日记(函数)

函数的概念

输入——>函数体:完成某种功能——>输出(独立的黑匣子)

在C++中,可以将一段经常使用的代码封装起来,在需要使用时直接调用,这就是程序中的函数。

C++程序的执行是从main函数开始的,如果在main函数中调用了其他函数,在调用后程序返回到main函数,在main函数中结束整个程序的运行。

函数分为:无参函数和有参函数

函数的声明

先声明,后使用。

如果需将函数定义放在函数调用后,我们需要采用函数声明的方式。
格式:

函数返回值类型   函数名称(形参列表)
int select_biggest(int a,int b,int c);

函数原型:函数返回类型、函数名称和形参列表
函数声明后有分号,是语句。

函数声明可以定义在函数外部,则当前文件从声明位置到文件结束的任何函数中都可以调用该函数。

函数定义包括函数头和函数体,函数声明是为了编译的需要,知道这个函数的基本信息。

函数声明在头文件中更加美观和容易修改重利用。

函数的定义

无参函数:

函数返回值类型(可以是void) 函数名()
{
定义部分
语句部分
(有返回值是一定要有return语句)
}

有参函数

函数返回值类型 函数名(形式参数列表)
{
定义部分
语句部分
}

函数的返回值

return语句的后面可以是一个值,也可以是能够得出值的表达式

C++函数中必须指定返回类型
可以使整型、浮点型、类类型、符合类型、或是空类型(void)

注意:函数返回值类型一般应该与return语句中的表达式类型一致,如果不一致应当以函数返回值(函数名前的类型)类型为准。

//函数返回类型与return类型不同
#include<iostream>
using namespace std;
 //声明函数,返回值为int类型
int select_biggest(int a, int b, int c); 
void main() 
{
    double a, b, c;
    cout << "a= ";
    cin >> a;
    cout << "b= ";
    cin >> b;
    cout << "c= ";
    cin >> c;
    cout << "The biggest number is " << select_biggest(a, b, c);//调用函数
    cout << endl;
    system("pause");
}
int select_biggest(int a, int b, int c)  //定义被调用函数
{
    double biggest;
    if (a > b)
        biggest = a;
    else
        biggest = b;
    if (biggest > c)
        return biggest;
    else
        return c;
}

这里写图片描述

函数的形参表

int get_bigger(int a,int b,int c);//right
int get_bigger(int a, b, c);//wrong

形参表可为空(不填或填void)

调用函数时,每一个实际参数的类型都必须与对应的形参类型相同,或者是可以转换成形参类型的数值类型。在这种情况下,实参会被隐式的转换成形参的类型,再进行数据传递。(实参被转换为形参类型、实参——>形参)

最好是实参和形参的类型保持一致,否则可能造成精度的缺失,导致效果不同。

函数的参数传递

非引用类型的形参,赋值的是值;
引用类型的形参,它只是实参的别名,不会赋值实参的值。

在定义函数的时候制定的形参,在没有出现函数调用时,并不占用内存中的存储单元。在发生函数调用时,函数中的形参才被分配内存单元,调用结束后形参所占用的内存单元也会被释放。

引用形参

//未使用引用形参的互换函数
#include<iostream>
using namespace std;
void swap(int x, int y); //声明函数
void main()
{
    int a = 10;
    int b = 20;
    //输出调用函数之前的a和b
    cout << "Before change :" << endl;
    cout << "After change :" << endl;
    swap(a, b); //调用函数,实参为a,b
    //输出调用函数之后的a和b
    cout << "a = " << a << " b = " << b << endl;
    system("pause");
}
void swap(int x, int y)
{
    int temp; 
    temp = x; //将x和y互换
    x = y;
    y = temp;
}

这里写图片描述
未达到互换的效果,因为执行swap时只是交换了实参的局部副本,a和b本身没有进行互换,利用引用形参可以做到。

//使用引用形参的互换函数
#include<iostream>
using namespace std;
void swap(int&, int&); //声明函数 注意形参为引用形参
void main()
{
    int a = 10;
    int b = 20;
    cout << "Before change :" << endl;
    cout << "a = " << a << " b = " << b << endl;//输出调用函数之前的a和b
    cout << "After change :" << endl;
    swap(a, b); //调用函数,实参为a,b
    cout << "a = " << a << " b = " << b << endl; //输出调用函数之后的a和b
    system("pause");
}
void swap(int &x, int &y)
{
    int temp;
    temp = x; //将x和y互换
    x = y;
    y = temp;
}

使用引用形参交换了实参的值
将形参直接关联到了其所绑定的对象(即实参上),而不是关联到实参的副本上。上例中,形参x和y只是实参a和b的名字,对x和y的任何修改实际上都是对a和b的修改。引用形参在C++中比较普遍和实用。

实用引用形参时需要注意以下几点:
(1)实用const引用形参可以避免复制实参为局部副本
(2)传递指向指针的引用 int *&a

//使用引用形参实现指针实参互换
#include<iostream>
#include<string>
using namespace std;
void swap(int*&, int*&);
void main()
{
    int a = 10;
    int b = 20;
    int *pointer1 = &a;
    int *pointer2 = &b;
    cout << "Before change :" << endl;
    cout << "pointer1 = " << pointer1 << " pointer2 = " << pointer2 << endl;
    cout << "*pointer1 = " << *pointer1 << " *pointer2 = " << *pointer2 << endl;
    cout << "a = " << a << " b = " << b << endl;
    cout << endl;
    swap(pointer1, pointer2);
    cout << "After change :" << endl;
    cout << "pointer1 = " << pointer1 << " pointer2 = " << pointer2 << endl;
    cout << "*pointer1 = " << *pointer1 << " *pointer2 = " << *pointer2 << endl;
    cout << "a = " << a << " b = " << b << endl;
    cout << endl;
    system("pause");
}
void swap(int *&x, int*&y)
{
    int *temp;
    temp = x;
    x = y;
    y = temp;
}

这里写图片描述
实参指针的值被交换了,所以其所指向的值也就发生了改变。
但只是改变了指针的值,并没有改变a和b本身。

函数的调用

调用形式:函数名(实参列表)
一般有三种情况:

//1.不需要返回值
print(s1,s2,s3);
//2.直接将函数的返回值作为表达式的一个操作数参与运算
c=multi(a,b)*multi(a,b);
//3.直接将函数调用作为另一个函数调用的实参
biggest=bigger(a,bigger(b,c));

函数的嵌套调用

//函数嵌套
#include<iostream>
#include<string>
using namespace std;
int bigger(int, int);
int biggest(int, int, int, int);
void main()
{
    int a, b, c, d;
    cout << "Put in a : ";
    cin >> a;
    cout << "Put in b : ";
    cin >> b;
    cout << "Put in c : ";
    cin >> c;
    cout << "Put in d : ";
    cin >> d;
    int f = biggest(a, b, c, d);
    cout << "The biggest one is : " << f << endl;
    system("pause");
}
int biggest(int x, int y, int z, int k)
{
    return bigger(x, bigger(y, bigger(z, k))); //嵌套调用bigger函数
}
int bigger(int x, int y)
{
    return (x > y ? x : y);
}

内联函数

将程序中经常使用的简短操作定义为函数,可有效提高程序的可移植性及通用性。但是调用函数需要更多额外的工作,将函数定义为内联函数就是将它在程序中的每个调用点上展开。
在函数返回值前加inline就可以定义函数为内联函数

内联函数适用于优化短的、只有几行经常被调用的函数。
在类定义中分为显式内联函数和隐式内联函数;
显式:函数在类定义内声明,在类定义外定义函数本身;
隐式:直接在类定义内定义的函数。

指针和函数

函数的形参可以是指针*,这时将复制实参的指针为副本。

如果函数将新的指针复制给形参,主调函数中所使用的实参的值是没有任何变化的(这里的实参指的是指针变量本身)。

如果形参是非const类型的指针,则可通过指针实现赋值,修改主调函数中指针所指向对象的值。

//尝试通过形参指针修改实参指针指向的值
#include<iostream>
#include<string>
using namespace std;
void change(int *);
int main()
{
    int a = 10;
    int *pointer = &a;
    cout << "Before change :" << endl << endl;
    cout << "Pointer = " << pointer << endl;
    cout << "a = " << a << endl << endl;
    cout << "After change :" << endl << endl;
    change(pointer);
    cout << "Pointer = " << pointer << endl;
    cout << "a = " << a << endl << endl;
    system("pause");
}
void change(int *x)
{
    int c = 20;
    *x = c;//将c的值赋值给形参所指向的值,即a的值
    x = &c;//将c的地址赋值给形参x指针
    cout << "&c = " << &c << endl;
}

这里写图片描述
从结果可以看到,pointer指向的a的值发生变化,但其本身并没有变化。

//输出不及格学生的成绩
#include<iostream>
#include<string>
using namespace std;
double *search(double(*)[4]);
int main()
{
    double info[3][4] = { { 87, 56, 84, 69 }, { 56, 87, 69, 85 },
    { 88, 59, 82, 91 } };
    double(*p)[4];//定义一个指向二维数组的指针
    int i,j;
    p = info;
    cout << "学生的成绩为: " << endl;
    cout << "******************************************" << endl;
    cout << "         语文   数学   文综   理综" << endl;
    for (i = 0; i < 3; i++)
    {
        cout << "学生" << i + 1 << ":   ";
        for (j = 0; j < 4; j++)
            cout << *(*(p + i) + j) << "     ";
        cout << endl;
    }
    cout << endl;
    cout << "******************************************" << endl;
    cout << "输出不及格学生的学号及成绩:" << endl;
    for (i = 0; i < 3; i++)
    {
        //如果函数返回值与本行开头地址不同,则表示有不及格的
        if (search(p) != *(p + i))
        {
            cout << "学生" << i << " : ";
            for (j = 0; j < 4; j++)
                cout << *(*(p + i) + j) << " ";
            cout << endl;
        }
    }
    cout << endl;
    system("pause");
}
double *search(double(*p)[4])
{
    double *point;
    int i;
    point = *(p + 1);//将point指向本行的末尾
    for (i = 0; i < 4; i++)
    {
        if (*(*p + i) < 60)
            //本行中若有不及格的则将point指向本行的开头
            point = *p;
    }
    return point;
}

这里写图片描述

函数重载

重载函数:两个函数具有相同的名字,但形参表不同,并且两者处于同一个作用域之中。

定义一组函数,需要使用这组函数执行一系列操作,但是它们是应用在不同的参数类型上时即可选择重载函数。

函数重载可以使程序变得更加容易理解和通用。

//函数重载
#include<iostream>
using namespace std;
int test(int a, int b);
float test(float a, float b); //重载函数
void main()
{
    cout << test(1, 2) << endl << test(2.1f, 3.14f) << endl;//重载调用
    cin.get();
}
int test(int a, int b)
{
    return a + b;
}
float test(float a, float b)
{
    return a + b;
}

这里写图片描述

重载与作用域
重载函数应当定义在一个作用域当中,最好都放在头文件当中。
否则局部作用域和全局作用域会相互屏蔽重载函数。

默认参数
在函数声明或定义时直接对参数赋值即为默认参数。
在函数调用时没有指定与形参相对应的实参时,就自动使用默认参数。

  1. 默认参数在声明中设定一次
  2. 默认参数定义顺序为自右向左,如果一个参数设定默认值,其右边的参数都需要设定。
    int example(int a, int b=3, int c=6, int d=8);

  3. 默认参数调用时按顺序调用,即自左向右。(中间不能有空缺)

  4. 默认值可以是全局变量、全局常量,甚至是一个函数,但不能是局部变量。

    参数类型上不同的重载函数

//根据函数类型的差异进行函数重载
#include<iostream>
using namespace std;
int abd(int x)
{
    if (x < 0) x = -x;
    return x;
}
float abd(float x)
{
    if (x < 0)  x = -x;
    return x;
}
double abd(double x)
{
    if (x < 0) x = -x;
    return x;
}
void main()
{
    int a = -314;
    float b = 3.141;
    double c = -3.14159;
    cout << "int类型的a=-314的绝对值为: " << endl;
    cout << abd(a) << endl;
    cout << "float类型的a=-314的绝对值为: " << endl;
    cout << abd(b) << endl;
    cout << "double类型的a=-314的绝对值为: " << endl;
    cout << abd(c) << endl;
    cin.get();
}

这里写图片描述

参数个数上不同的重载函数

//根据函数个数的差异进行函数重载
#include<iostream>
using namespace std;
int max(int x, int y)
{
    if (x > y)
        return x;
    else
        return y;
}
int max(int x, int y,int z)
{
    int a = max(x, y);
    return max(a, z);
}
int max(int x, int y,int z,int k)
{
    int a = max(x, y, z);
    return max(a, k);
}
void main()
{
    cout << "求两个整数56,45中的最大值:" << endl;
    cout << max(56, 45) << endl;
    cout << "求三个整数72,98,15中的最大值:" << endl;
    cout << max(72, 98,15) << endl;
    cout << "求四个整数12,65,47,54中的最大值:" << endl;
    cout << max(12, 65, 47, 54) << endl;
    cin.get();
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/michaelzzk/article/details/79857839
今日推荐