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

size_t get_count()
{
static size_t count = ;
return ++count;
}

2.当实参初始化形参的时候会忽略顶层const,换句话说,当形参有顶层const时,传给它常量或者非常量都是可以的。

const int ci = ;    // ci的值不能被改变,const是顶层的
int i = ci; // 当拷贝ci时, 忽略了它的顶层const void fun(const int i){}
void fun(int i){} // 错误,重复定义

3.数组在做形参的时候是不允许拷贝数组的,而且数组通常会被转换为指针。

// 以下三个声明是等价的,编译器只会检查参数是否为int*
void printArr(int *arr);
void printArr(int arr[]);
void printArr(int arr[]);

4.如果想固定数组的大小,可以使用引用形参。

void printArr(int(&arr)[]) {}
int arr[] = { };
printArr(arr); // 错误,arr不是长度为10的数组

5.如果函数的实参数量未知,但类型都相同,可以使用 initializer_list 类型的形参,initializer_list是一种标准库类型,可以表示某种特定类型的值的数组。它和 vector 一样都是模板类型,但是不可以修改它的元素。

initializer_list<int> lt = { , ,  };

6.省略符形参应该仅仅用于C和C++通用的类型,大多数类类型的对象在传递给省略符形参的时候无法正确的被拷贝。而且省略符形参只能出现在形参列表的最后一个位置。

void fun(...) {}
void fun1(int, ...) {} // 其中的逗号可以省略
fun1(, "test", "test2");

7.如果函数的返回类型不是void那么必须返回一个值,但是main函数可以例外,允许main函数没有return也可以正常结束,编译器将隐式的为main函数加入一个返回0的return语句。

8.main函数不可以递归,也不可以重载。

9.因为数组不能拷贝,所以函数不能返回数组,不过函数可以返回数组的指针或引用。

// 使用别名的方式
typedef int arrT[];
using arrT = int[];
arrT* func(int i);
// 不使用别名的方式
int (*func(int i))[10];
// 尾置返回类型的方式(C++ 11)
auto func(int i) -> int(*)[10];
// decltype 的方式(C++ 11)
int arr[];
decltype(arr) *func(int i);

10.如果在函数内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体。即在不同的作用域中无法重载函数名。

std::string read();
void print(const string&);
void print(double); void Test()
{
bool read = false; // 新作用域,隐藏了外层的read
std::string s = read(); // 错误,read是个bool值
void print(int); // 新作用域,隐藏了外层的print
print("test"); // 错误,print(const string&)已被隐藏
print(); // 正确
print(3.14); // 正确,调用的是print(int)
}

11.constexper函数是指能用于常量表达式的函数,要遵循两个规定,函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句

constexpr int count() { return ; }
constexpr int i = count();

12.允许constexpr函数的返回值并非一个常量

constexpr int count() { return ; }
constexpr int total_count(std::size_t num) { return num * count(); };

但是上述的参数num如果给的不是一个常量,则编译器会发出错误信息。

13.和其他函数不一样,内联函数和constexpr函数可以在程序中多次定义,但是它的多个定义必须完全一致,基于这个原因,内联函数和constexpr函数通常定义在头文件中。

14.assert的行为依赖于一个名为NDEBUG的预处理变量的状态,如果定义了NDEBUG,则assert什么也不做。

15.当编译器无法找出最佳匹配的函数时会产生二义性的错误,我们可以使用强制类型转换来避免,但这不是一个好的选择。

void pritf(int, int);
void pritf(double, double); pritf(, 3.14); // 编译器不知道该匹配哪个函数,产生二义性错误

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

int get_max(int a, int b);
int (*pf)(int, int); // pf指向一个函数,该函数返回值是int(如果*pf不加括号,函数的返回值就是int*) // 以下两个初始化等价
pf = get_max;
pf = &get_max; //以下两个调用等价
int i = pf(, );
int j = (*pf)(, );

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

// 以下两个声明等价
void use_max(int a, int b, int pf(int,int));
void use_max(int a, int b, int (*pf)(int, int)); // 我们可以直接把函数作为实参使用,此时它会自定转换成指针
use_max(, , get_max);

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

int get_max(int a, int b);

// 使用别名
using F = int(int, int);
using pF = int(*)(int, int); pF f1(int); // 正确
F f2(int); // 错误,返回类型不会自动地转换成指针
F *f3(int); // 正确 // 当然我们也能不用别名的形式直接声明
int (*f4(int))(int, int); // 使用auto或者decltype
auto f5(int) -> int(*)(int, int);
decltype(get_max) *f6(int, int);

C++ Primer 笔记——函数的更多相关文章

  1. C++ Primer笔记

    C++ Primer笔记 ch2 变量和基本类型 声明 extern int i; extern int i = 3.14;//定义 左值引用(绑定零一变量初始值,别名) 不能定义引用的引用:引用必须 ...

  2. Python编程从入门到实践笔记——函数

    Python编程从入门到实践笔记——函数 #coding=gbk #Python编程从入门到实践笔记——函数 #8.1定义函数 def 函数名(形参): # [缩进]注释+函数体 #1.向函数传递信息 ...

  3. 《python基础教程(第二版)》学习笔记 函数(第6章)

    <python基础教程(第二版)>学习笔记 函数(第6章) 创建函数:def function_name(params):  block  return values 记录函数:def f ...

  4. C++ Primer 笔记(1)基础中的战斗机 输入输出 对输入不定数据处理

    今天打算再重新好好的看一遍C++ Primer这本很经典的书籍,笔记开始: 1.每个C++程序都包含一个或者多个函数,其中必须有一个main,操作系统通过调用main入手运行程序: 2.函数包括:返回 ...

  5. C++ Primer 笔记 第一章

    C++ Primer 学习笔记 第一章 快速入门 1.1 main函数 系统通过调用main函数来执行程序,并通过main函数的返回值确定程序是否成功执行完毕.通常返回0值表明程序成功执行完毕: ma ...

  6. C++primer笔记之顺序容器

    最近又重新拾起C++primer,发现每一次看都会有不同的体验,但每一次看后因为不常用,忘记得很快,所以记笔记是很关键的一环,咋一看是浪费时间,实际上是节省了很多时间.下面就把这一节的内容做一个简单的 ...

  7. c++ primer 笔记 (一)

    昨天开始看的<C++ Primer>,确实不错.希望这周抓紧看完,每天做下笔记,以便以后复习. main函数返回一个值给操作系统   操作系统通过main函数返回的值来确定程序是否成功执行 ...

  8. C++Primer笔记(3)

    标准库类型string表示可变长的字符序列,使用前先包含string头文件.(哈哈,终于可以逃脱C语言中的str函数系列了.)因为是标准库的一部分,所以string被定义在命名空间std中.所以你懂该 ...

  9. C++ Primer 笔记 第三章

    C++ Primer 第三章 标准库类型 3.1using声明 例: using namespace atd; using std::cin; 3.2string类型 初始化方式 string s1 ...

随机推荐

  1. Centos7 nginx提示错误 Access denied.

    SELinux will cause this error on CentOS/RHEL 7+ by default :( CentOS/RHEL 7+ 系统默认会因为SELinux出现这个报错 To ...

  2. 20165237 2017-2018-2 《Java程序设计》第十周考试补做及编程题

    20165237 2017-2018-2 <Java程序设计>第十周考试补做及编程题 知识点 1.链表是由若干个称作节点的对象组成的一种数据结构,每个节点含有一个数据和下一个节点的引用 . ...

  3. Debian 为firefox安装flash插件 以及 音频驱动

    1. flash下载地址:http://get.adobe.com/cn/flashplayer/ lv@lv:~/Downloads$ tar -zxvf flash_player_npapi_li ...

  4. 【ARTS】01_20_左耳听风-20190325~20190331

    zz## ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 ...

  5. C/S 开发框架 ----- 广州本地

    C/S 开发框架 -----  广州本地: 1) 爱奇迪    http://www.iqidi.com       发现一个源码出售站   http://www.51aspx.com/code/co ...

  6. powerdesigner 使用技巧 建模工具 导出sql 导出实体类 导出word

    显示comment列 Table Properties(表属性)=>Columns(列)=>Customize Columns and Filter(自定义列过滤) 勾上 comment ...

  7. hibernate框架学习第一天:hibernate介绍及基本操作

    框架辅助开发者进行开发,半成品软件,开发者与框架进行合作开发 Hibernate3Hibernate是一种基于Java的轻量级的ORM框架 基于Java:底层实现是Java语言,可以脱离WEB,在纯J ...

  8. Unity3D Shader 入门

    什么是Shader Shader(着色器)是一段能够针对3D对象进行操作.并被GPU所执行的程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出.绘图单元可以依据这 ...

  9. DALSA相机开发--修改参数

    DALSA gige相机有两种方式可以获取到相机相关参数,一个是读取相机里面的xml文件:另外一个是读取相对应的寄存器的值. 对于修改寄存器的值,有两个相应的函数: 1)GevSetFeatureVa ...

  10. Zabbix3.0.4监控Windows的CPU使用百分比并在CPU使用率超过90%触发报警

    Zabbix3.0.4监控Windows的CPU使用百分比 Zabbix 自带的模块没有 CPU 使用率(百分比)这个监控项,我们可以通过添加计数器的方式实现 CPU 百分比的监控. 1.在Zabbi ...