Skip to content

函数

约 666 个字 39 行代码 1 张图片 预计阅读时间 4 分钟

参数传递

传值参数

  • 实参的值不变
  • 初始值被拷贝给变量

传指针

  • 拷贝的是指针,两个指针不同,但指向相同的对象

  • 可以改变实参的值

传引用参数

  • 绑定了初始化它的对象
  • 避免拷贝
  • 函数不需要改变引用形参的值,声明成常量引用

const形参和实参

  • 实参初始化形参时会忽略掉顶层const
  • 尽可能使用常量引用

数组形参

C++
void print(const char *cp);
void print(const int *beg, const int *end); // 传递指向数组首部和尾部的指针
void print(const int ia[], size_t size);
void print(int (&arr)[10]);
void print(int (*arr)[10]); // 传递多维数组

可变形参

  • initializer_list形参:参数数量未知但全部实参类型相同
  • 该对象中的元素永远是常量值

省略符形参

  • 使用了varargs的C标准库功能
  • 省略符形参只能出现在形参列表的最后一个位置

返回值

  • 变量的递减操作和读取变量值的操作共存于同一条表达式中,可能产生未定义的值
C++
int &get(int *array, int index) {return array[index];}  //获取数组中Index元素的索引
int main()
{
    int ia[10];
    for(int i = 0; i != 10; ++i)
        get(ia, i) = i;
}

返回一个值

  • 拷贝调用点的一个临时对象,该临时对象即为返回结果
  • 不要返回局部对象的指针或引用

  • 引用返回左值;其他类型返回右值

  • 列表初始化返回值:对返回的临时量进行初始化

声明一个返回数组指针的函数

C++
int (*func(int i))[10];
// 尾置类型
auto func(int i) -> int(*)[10];
// decltype
int odd[] = {1,3,5,7,9};
int even[] = {2,4,6,8,10};
decltype(odd) *arrPtr(int i) {
    return (i % 2) ? &odd : &even;
}

函数重载

  • 不区分顶层const的形参
  • 注意重载函数的作用域

默认实参

  • 函数声明中指定默认实参,并将声明放在合适的头文件中
  • 局部变量不能作为默认实参

内联函数

  • 在每个调用点“内联地”展开
  • 内联机制用于优化规模较小,流程直接,频繁调用的函数

constexpr函数

  • 常量表达式的函数
  • 返回类型和所有形参的类型均是字面值类型,函数体有且只有一条return语句
C++
constexpr int new_sz(){return 42;}
constexpr int foo = new_sz();

实参类型转换

  • 精确匹配
  • 形参和实参类型相同
  • 实参由数组或函数转换成对应的指针
  • 向实参中添加/删除顶层const
  • const转换实现的匹配(非常量的地址转换成const的地址)
  • 类型提升(小整数类型转换为大整数类型)
  • 算数类型转换或指针转换(在运算中类型改变)
  • 即使很小的整数值也会直接提升成int类型
C++
void ff(int);
void ff(short);
ff('a');    // char提升成int,调用ff(int);
  • 类类型转换实现的匹配

二义性

  • 所有的算数类型转换级别都相同
C++
void manip(long);
void manip(float);
manip(3.14);
// 既可以转换成float也能转换成long

函数指针

C++
bool (*pr)(const string&, const string&);
pr = lengthCompare;
pr = &lengthCompare;

bool b1 = pr("hello", "goodbye");
bool b2 = (*pr)("hello", "goodbye");

将auto和decltype用于函数指针类型

C++
auto f1(int) -> int(*)(int*, int);
string::size_type sumLength(const string&, const string &);
decltype(sumLength) *getFcn(const string &);    // 使用decltype作用某个函数时,返回函数本身类型而非指针类型