c++中的一些函数类型介绍

64 篇文章 0 订阅

使用数组区间的函数

  • 例子:数组:array+m ~ array+n == array[m-1] ~ array[n-1]
  • array ~ array+n == array[0] ~ array[n-1]
// arrfun4.cpp -- functions with an array range
#include <iostream>
const int ArSize = 8;
int sum_arr(const int * begin, const int * end);
int main()
{
    using namespace std;
    int cookies[ArSize] = {1,2,4,8,16,32,64,128};
// some systems require preceding int with static to
// enable array initialization

    int sum = sum_arr(cookies, cookies + ArSize);
    cout << "Total cookies eaten: " << sum << endl;
    sum = sum_arr(cookies, cookies + 3); // first 3 elements
    cout << "First three eaters ate " << sum << " cookies.\n";
    sum = sum_arr(cookies + 4, cookies + 8); // last 4 elements
    cout << "Last four eaters ate " << sum << " cookies.\n";
    return 0;
}

// return the sum of an integer array
int sum_arr(const int * begin, const int * end)
{
    const int * pt;
    int total = 0;

    for (pt = begin; pt != end; pt++)
        total = total + *pt;
    return total;
}

函数指针

  • 格式:数据类型(*函数名xxx)(argument1,argument2,…);
  • 也可以这样写:先编写这种函数的原型,然后用(*xxx)替换这种函数名
double pam(int);
double (*pf)(int);

pf = pam;              // pf now points to the pam() function
double x = pam(4);  // call pam() using the function name
double y = (*pf)(5); // call pam() using the pointer pf

pf与(*pf)等价!!!
double y = pf(5); // also call pam() using the pointer pf

高级应用

const double * f1(const double ar[], int n);
const double * f2(const double [], int);
const double * f3(const double *, int);

const double * (*p1)(const double *, int);
初始化
const double * (*p1)(const double *, int) = f1;
自动类型推断
auto p2 = f2; // C++11 automatic type deduction
前半部分输出地址,后半部分输出值
cout << (*p1)(av,3) << ": " << *(*p1)(av,3) << endl;
cout << p2(av,3) << ": " << *p2(av,3) << endl;

函数指针数组

  • 格式:数据类型(*函数名[n])(argument1,argument2,…);
  • 格式:数据类型 *(*函数名[n])(argument1,argument2,…);
初始化
const double * (*pa[3])(const double *, int) = {f1,f2,f3};
  • 包含3个函数指针的数组,数组中每个指针都指向这样的函数:const double * 和 int作为参数,并且返回一个const double *

调用
const double * px = pa[0](av,3);
const double * py = (*pb[1])(av,3);

取值
double x = *pa[0](av,3);
double y = *(*pb[1])(av,3);

创建指向整个数组的指针,pa是一个包含了函数指针的数组,所以pa是指向函数指针的指针
auto pc = &pa; // C++11 automatic type deduction
等价于下面
const double *(*(*pd)[3])(const double *, int) = &pa;
1. pd指向数组,*pd就是数组,(*pd)[i]是数组中的元素:函数指针。所以函数调用是:(*pd)[i](av,3),而*(*pd)[i](av,3)返回指针指向的值。
2. 函数调用是:(*(*pd)[i])(av,3),而*(*(*pd)[i])(av,3)返回指针指向的值。
注意:pa和&pa的区别
  • pa指第一个元素的地址,&pa指整个数组的地址,两者的值相等,但类型不相等。
  • pa+1指数组中下一个元素的地址,&pa+1指数组pa后面的内存块的地址,所以要得到第一个元素的值:
  • **&pa == *pa == pa[0]

宏函数(带参数的宏)的缺点

  • 在c中把一些短,执行频率高的计算写成宏,而不是函数,这样做是为了提高执行效率,宏可以避免函数调用的开销,这些都由预处理完成。
  • 在c++中使用预处理宏会出现问题:
    1.宏看起来像一个函数调用,但会隐藏一些错误。
    2.c++特有:预处理器不允许访问类的成员,即预处理器宏不能用作类的成员函数。
  • 为了解决上述问题,引入内联函数。
  • 宏如以下问题:
    在这里插入图片描述

内联函数

  • 为了继承宏函数的效率,没有函数调用时的开销(出入栈),也可以像普通函数那样在类中访问,作为成员函数。
  • 任何在类内部定义的函数自动成为内联函数,目的为了提高效率。
  • 内联函数的运行速度比常规函数稍快,但是占用内存更多
  • 在函数声明 / 定义前面加上关键字:inline
  • 函数定义可以放在一行中,但不一定非要这样做,。如果占用多行,将其作为内联函数也不合适。
  • 不是让程序跳到独立的代码段执行函数,而是用相应的代码代替函数调用,只有在函数很短时才可以采用内联函数。
  • 内联函数在编译器中完成。
  • 条件:
    1.不能有循环语句
    2.不能有判断语句
    3.函数体不能太大,不能对函数进行取地址操作。

函数的默认参数

  • 如果某个位置已经有了默认参数,那么从这个位置往后必须有默认值。
  • 如果函数声明有默认参数,则函数实现不能有默认参数。两者中只能有一个有默认参数。

函数占位参数

  • 函数名(数据类型1,数据类型2,…){}
  • 也可以有默认参数
  • 例子:void func(int a , int , int = 10){}

函数重载

  • 满足条件:1.同一个作用域下。2.函数名相同。3.**函数参数类型不同,或个数不同,或顺序不同。**即:特征标不同。
  • 把类型引用和类型本身看成同一个特征标。
  • 匹配函数时,区分const和非const变量。
  • 函数模板自动完成函数重载过程。
  • 函数传参时,非const值赋给const是合法的,反正非法。
double cube(double x);
double cube(double & x);
错误示例
  • 函数的返回值不可以作为重载的条件。

引用作为重载的条件

在这里插入图片描述

函数重载碰到默认参数

  • 使用函数时会出现二义性

函数和链接性

  • 类似于单定义规则。
  • 不允许在一个函数中定义另外一个函数。
  • 默认情况下,函数的链接性为外部,可以在文件中共享。
  • 使用static将函数的链接性设置为内部,必须在原型和定义中使用static。这意味着在其他文件中可以定义同名的函数。
  • 内联函数属于内部链接,可以将内联函数的定义放在头文件中。
static int private(double x);
...
static int private(double x)
{
    ...
}

c++查找函数的方式

  • 如果为静态函数,只在该文件中查找函数定义。
  • 否则,编译器将在所有程序文件中查找。
  • 如果没有找到,在库函数中查找。

语言链接性

  • c++语言链接:c++执行名称矫正或名称修饰,为重载函数生成不同的符号名称。
  • 例子:函数spiff(int)转换为:_spiff_i,将spiff(double,double)转换为:_spiff_d_d。
  • 使用函数原型指出要使用的约定:
c语言链接:
extern "C" void spiff(int);   // use C protocol for name look-up

c++语言链接:
extern void spoff(int);       // use C++ protocol for name look-up
extern "C++" void spaff(int); // use C++ protocol for name look-up
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值