函数基础

点击查看

局部对象

1.自动对象

只存在于块的执行期间的对象被称为自动对象。

当函数的控制路径经过变量定义语句时创建该对象,当到达定义所在的块末尾时销毁它,当块的执行结束时,块中创建的自动对象的值就变成未定义的了。

形参就是一种自动对象,我们用传递给函数的实参初始化形参对应的自动对象。

2.局部静态对象

一般来说,存在于函数体中的局部变量的生命周期只局限于函数体,但我们可以通过将局部变量定义成static类型来让其生命周期贯穿函数调用以及之后的时间。这就是局部静态对象。

局部静态对象值的默认初始化与全局变量一样。

函数声明

函数的声明不包含函数体,也可以省略形参列表。

函数声明中包含了函数的三要素(返回类型,函数名,形参类型),函数的三要素描述了函数的接口,说明了调用该函数所需的全部信息。函数声明也称作函数原型。

建议将函数声明和定义分开,在源文件中定义,在头文件中声明。这样,一旦我们想改变函数的接口,只需要改变一条声明即可。

分离式编译

c++primer p186-187

参数传递

点击查看

每次调用函数的时候都会重新创建它的形参,并用传入的实参对形参进行初始化。

当形参是引用类型时,它对应的实参被引用传递或者说函数被传引用调用。

当实参的值被拷贝给形参时,实参被值传递或者说函数被传值调用

传值参数

当初始化一个非引用类型的变量时,初始值被拷贝给变量。对变量的改动不会影响初始值

指针形参

当执行指针拷贝操作时,拷贝的是指针的值。拷贝之后,两个指针是不同的指针。

1
2
3
4
5
6
7
8
9
void reset(int *p){
*p = 0;//改变了p所指对象的值, i = 0
p = 0;.//只改变p的局部拷贝,实参并未改变
}

int main(){
int i = 42;
reset(&i);
}

传引用参数

1.通过传引用参数, 允许函数改变实参的值

2.通过引用来避免拷贝

例如, 编写一个函数比较两个string对象的长度

1
2
3
bool isShorter(const string &sl, const string &s2){
return s1.size() < s2.size();
}

注意,当函数无须修改引用形参的值时最好使用常量引用

3.可以通过引用形参返回额外信息

const形参和实参

1.当用实参初始化形参时会忽略掉顶层const,也就是说当形参有顶层const时, 传给他常量对象或者非常量对象都是可以的,反过来不行

1
2
void fcn(const int i){}
void fcn(int i){}//错误,重复定义了fcn,因为上一句的顶层const被忽略了

2.尽量使用常量引用

原因:c++primer p192

数组形参

1.由于数组的特殊性质,数组不允许拷贝,以及使用数组时通常会转化成指针。

1
2
3
4
void print(const int*);
void print(const int[]);
void print(const int[10]);
//以上三个函数是等价的,每个函数的唯一形参都是const int*类型

2.管理指针形参有三种常用的技术

c++ primer p194

3.数组引用形参

形参可以是数组的引用

1
2
3
4
void print(int (&arr)[10]){//形参是数组的引用,括号不能少,不然就声明成了引用的数组
for(auto elem : arr)
cout << elem << endl;
}

4.传递多维数组实际上就是传递数组首元素的指针,由于首元素本身就是一个数组,所以指针就是一个指向数组的指针。

main:处理命令行选项

c++primer p196

含有可变形参的函数

有时候我们无法预知应该传递几个实参,c++11提供了两个主要的方法:

1.如果所有的实参类型都相同,可以传递一个名为initializer_list的标准库类型;

2.如果实参的类型不同,可以编写可变参数模板

c++primer p198

省略符形参通常是以下两种形式

1
2
void foo(parm_list, ...);
void foo(...);

返回类型和return语句

点击查看

无返回值函数

有返回值函数

返回数组指针

函数重载

点击查看

重载与作用域

特殊用途语言特性

点击查看

默认实参

内联函数和constexpr函数

调试帮助

函数匹配

点击查看

实参类型转换

函数指针

点击查看