【修炼C++】基础知识点笔记-第6章 函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/albert19891108/article/details/84349817

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

void fcn(const int i){}

void fcn(int i )//错误:重复定义了fcn(int)

因为顶层const被忽略掉了,所以在上面的代码中传入两个fcn函数的参数可以完全一样。

2 尽量使用常量引用,因为若定义为常量引用,则说明 1 这个参数不能被改变,2 可以赋予常量引用以字面型常量(如int string类型常量),普通的引用形参的局限性在于不能把const对象,字面值或者需要类型转换的对象

3 数组有两个特殊的性质,

1) 不允许拷贝数组。 如 int a[10] = {0};int b [] = a; b = a; //后两种行为都是非法的。

2)使用数组时会将其转换成指针。

4 数组引用形参

//形参是数组的引用,维度是类型的一部分
void print(int (&arr)[10])
{
    for(auto elem:arr)
        cout<<elem<<endl;
}

注意的是数组引用的形式

int &arr[10];//错误:数组中需要为一个对象,引用非对象 
int (&arr)[10];//arr是具有10个整数的整型数组的引用

int (*arr)[10]; //arr为指向数组的指针
int *arr[10];   //arr为指针数组

5 传递多维数组

当将多维数组传递给函数时,真正传递的是指向数组首元素的指针。首先元素本身就是一个数组,指针就是一个指向数组的指针。数组的第二维(以及后面所有维度)的大小都是数组类型的一部分,不能忽略。

void print(int (*matrix)[10],int rowsize){/*...*/}
void print(int matrix[][10], int rowsize){/*...*/}

6 含有可变形参的函数

原因:程序无法提前预知应该向函数传几个实参数。

1 C++11新标准标准提供了两种主要的方法:

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

2)如果实参的了性不同,我们可以编写一种特殊的函数,也叫做可变参数模版;

initializer_list 是一种标准库类型,用于表示某种特定类型的值得数组。与vector类似,有类似的操作但是不同点在于initializer_list中的元素是不可修改的,为常量值

initializer_list<T> lstl;默认初始化:T类型元素的空列表。
initializer_list<T> lst{1,b,c...};lst的元素数量和初始值一样多;lst的元素是对应初始值的副本;列表中的元素是const;
lst2(lst);    //拷贝或复制一个initializer_list对象不会拷贝列表中的元素;
lst2 = lst;   //拷贝后,原始列表和副本共享元素
lst.size();   //列表中的元素数量
lst.begin();  //返回指向lst中首元素的指针
lst.end();    //返回指向lst中尾元素下一位置的指针

2 省略符形参是为了便于C++程序访问某些特殊的C代码而设置的,应该仅仅用于C和C++通用的类型。

void foo(param_list,...)
void foo(...)

7 列表初始化返回值

C++11新标准规定,函数可以返回花括号包围的值得列表。此处列表也用来对表示函数的临时量进行初始化。因此返回值得类型需要可以被列表初始化。

8 返回数组指针

数组不可以被拷贝,因此函数不能返回数组。想要定义一个返回数组的指针或引用的函数。

1) 使用类型别名。

typedef int arrT[10];
using arrT = int[10];

arrT* func(int i)//func返回一个指向含有10个整数的指针

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

形式如:

Type (*function(parameter_list))[dimension]

3) 使用尾置返回类型

c++11新标准中还有一种可以简化上述func声明的方法,就是尾置返回类型(trailing return type)。

//返回一个指针,指向含有10个整数的数组
auto func(int i) -> int(*)[10];

4) 使用decltype返回数组类型

int odd[] = {1,3,5,7,9};
int even[] = {0,2,4,6,8};

decltype(odd) *arrPtr(int i)
{
    return (i&2) ? &odd:&even;
}

9 inline内联函数,内联说明只是向编译器发出一个请求,编译器可以选择忽略这个请求。

一般来说,内联机制用于优化规模较小,流程直接,频繁调用的函数。

10 constexpr函数是指用于常量表达式的函数。

函数的返回值类型以及所有形参的类型都得是常量(需要在编译器确定),(若为非字面值类型,则为非常量表达式),而且函数体中必须有且只有一条return语句。

11 对于某个给定的内联函数或者constexpr函数来说,它的多个定义必须完全一致。基于这个原因,内联函数和constexpr函数通常定义在头文件中。

12 const_cast和重载

const_cast在重载函数的情景中最有用,当一个函数它的形参是一个常量,但是实参不是一个常量,可以通过const_cast转换来实现。

const string &shortString(const string &s1,const string &s2)
{
    return s1.size()<s2.size() ? s1:s2;
} 

string &shortString(string &s1, string &s2)
{
    auto &r = shorterString(const_cast<const string&>(s1),const_cast<const string&>(s2));
    
    return const_cast<string&>(r);
}

13 assert()在cassert文件中

NDEBUG 预处理变量,可以在文件中设置,也可以在编译选项中设置-D NDEBUG

--FILE--

--LINE--

--TIME--

--DATE--

14 返回指向函数的指针应当注意的是当我们将decltype作用于某个函数时,它返回函数类型而非指针类型,因此我们需要显式的加上*以表示需要返回指针类型。

/*--------1---------*/
using F = int(int*,int);
using PF = int(*)(int*,int);

PF f1(int);//PF是指向函数的指针,f1返回指向函数的指针
P *F1(INT);
/*--------2---------*/

int (*f1(int))(int*,int);
/*--------3---------*/

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

/*--------4---------*/

string::size_type sumLength(const string&,const string&);
string::size_type largerLength(const string&,const string&);

decltype(sumLength) *getFcn(const string &);

--------------------------------------------------------

6.3.3节练习

string(&func(para))[10];

typedef string arrT[10];
using arrT = string[10];

arrT& func(para);

//decltype(arrS) 返回的是数组类型,因此需要加一个&
string arrS[10];
decltype(arrS) &func(para);

auto func()->string(&)[10];

猜你喜欢

转载自blog.csdn.net/albert19891108/article/details/84349817
今日推荐