c++ primer 5 第6章 函数

来源:互联网 发布:阿里云 1m带宽 编辑:程序博客网 时间:2024/05/29 19:52

1.函数基础,基本概念

1.1局部对象

函数体是一个语句块,块构成一个新的作用域,我们可以在其中定义变量,形参和函数体内部定义的变量统称为局部变量。

1.2自动对象

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

1.3局部静态变量(static)

局部静态变量在程序的执行路径第一次经过对象定义语句时初始化,并且直到程序终止时才被销毁,在此期间即使所在的函数结束执行也不会对他有影响。

eg.统计函数本身被调用了多少次,可用一个statcic变量


2.参数传递

每次函数调用时都会重新创建它的形参,并用传入的实参对形参进行初始化。形参初始化的机理与变量初始化一样。

形参的类型决定了形参和实参交互的方式。如果形参是是引用类型,它将绑定到对应的实参上;否则,将实参的值拷贝后赋给形参。

2.1传值参数

.指针形参

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


2.2传引用参数

.当某种类型不支持拷贝操作时,函数只能通过引用形参访问该类型的对象。

.使用引用形参返回额外信息


2.3const形参和实参

当用实参初始化形参时会忽略掉顶层const。当形参是顶层const时,传给它常量对象或者非常量对象都是可以的。

.我们可以使用非常量来初始化一个底层const对象,但反过来不行。

.尽量只用常量引用,因为我们无法把const对象、字面值、常量或需进行类型转换的对象传递给普通形参。


2.4数组形参

.当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针。

eg.void print(const int*);

void print(const int[]);

void print(const int[10]);//三者等价

因为数组是以指针的形式传递给函数的,所以函数一开始并不知道数组的确切尺寸,调用者应该为此提供一些额外信息。

三种方法:1)使用标记指定数组长度;2)使用标准库规范;3)显示传递表示数组大小的形参


3.含有可变形参的函数

initializer_list形参。

省略符形参。


4.返回类型

4.1值是如何被返回的?

返回一个值的方式和初始化一个变量或形参的方式完全一样:返回的值用于初始化调用点的一个临时变量,该临时变量就是函数调用的结果。

.不要返回局部对象的引用或指针

.引用返回左值

.列表初始化返回值

c++11规定函数可以返回花括号包围的值的列表

eg.vector<string> process()

{

//......

if(expected.empty())

return {};

else if(expected==actual)

return {"functionX","okay"};

else

return {"functionX",expected,actual};


4.2返回数组指针

因为数组不能被拷贝,所以函数不能返回数组

typedef int arrT[10];

using arrT=int[10];

arrT* func(int i);


auto func(int i)->int(*)[10];//使用尾置返回类型


int odd[]={1,3,5,7,9};

decltype(odd) *arrPtr(int i)

{

return (i%2)?&odd:&even;

}


5函数重载

5.1重载和const形参

顶层const不影响传入函数的对象,一个用于顶层const和没有顶层const的形参区分开来。

5.2const_cast和重载

eg.string &shorterString(string &s1,string &s2)

{

auto &r=shorterString(const_cast<const string&>,const_cast<const string&>(s2);

return const_cast<string &>(r);

}


6constexpr函数

是指能用于常量表达式的函数,函数的返回类型及所有形参的类型都得是字面值类型。

在执行该初始化任务时,编译器把对constexpr函数的调用替换成其结果值。



7函数指针

函数指针指向的是函数而非对象。

7.1使用函数指针

当我们把函数名作为一个值使用时,该函数自动地转换成指针。

bool lengthCompare(const string &,const string &);

bool (*pf) (const string &,const string &);

pf=lengthCompare;


7.2函数指针形参

和数组类似,虽然不能定义函数类型的形参,但是形参可以是指向函数的指针。

eg.void useBigger(const string &s1,const string &s2,bool  pf(const string &,const string &));


7.3返回指向函数的指针

和数组类似,虽然不能返回一个函数,但是能返回指向函数的指针


eg.using F=int(int*,int);//F是函数类型,不是指针

using PF=int(*)(int* ,int);//PF是指针类型

PF  f1(int);//正确

F f1(int)//错误

F *f1(int);


int (*f1(int)) (int*,int)//直接声明f1


auto f1(int)->int(*)(int*,int);

原创粉丝点击