C++Primer 第六章
//1.我们通过调用运算符来执行函数。调用运算符的形式是一对圆括号,他作用于一个表达式,该表达式是一个函数或者指向函数的指针。圆括号之内是用逗号分隔的实参列表,用于初始化函数形参。调用表达式的类型就是函数的返回类型。 //2.实参是形参的初始值,尽管实参与形参存在对应关系,但是没有规定实参的求值顺序。 //3.任意两个形参不能同名,而且函数最外层作用域中的局部变量也不能和函数形参名字一样
void fun0(int value = )
{
//int value = 20; //error C2082: 形参“value”的重定义
{
int value = ; //正确
}
} //4.函数的返回类型不能是数组类型或者是函数类型,但是可以是指向数组或者函数的指针或引用。
// 数组的两个特殊性质:
// 不允许拷贝数组,导致无法以传值方式使用数组参数和返回数组类型
// 使用数组时通常将其转化为指针,导致我们为函数传递一个数组的时候,实际上传递的是指向数组首元素的指针。而这个指针将失去数组的所有特性,对于多维数组也是如此
void fun1(int a[]);
void fun1(int a[]);
void fun1(int *a);
// 以上三个函数的声明实际上是一致的,数组的第一个维度将被忽略。
void fun2(int (*a)[]);
void fun2(int (*a)[]);
// 以上两个函数的声明实际上是不一致的,数组的第二个及以上维度将不被忽略。int (*a)[10]可以看做是一个二维数组(第二个维度大小为10)的首地址。
// 对于多维数组,其除了第一维维度可以忽略外,其余维度是形参类型的一部分
// 在函数参数中,一维数组等价于一维指针,这是因为指针的偏移量可以通过指针类型得出
// 在函数参数中,二维数组不能等价于二维指针,这是因为指针的偏移量无法仅仅通过指针类型得出,还必须指定其第二维的长度才能知道
// 比如: int a[10], int* p在函数参数中是等价的,因为a[1]就等于指针p所指内存偏移4字节
// 而int a[2][2], int** p在函数参数中是不等价的,因为a[1]是数组首地址偏移了8字节,而p[1]无法正确的偏移8字节,所以多维数组除第一维外,其它的维度不可忽略
// 由上可以推出:在函数的参数中a[1][2] 和 a[1][3]是不同的,这是因为对于这两个二维数组来说a[0]的偏移量(相对于数组起始位置)一个是8字节,一个是12字节。 //5.不管是在定义变量还是在定义函数的形参列表的时候,要考虑好定义的基本类型,和其可变性。对于无符号的变量应定义为unsigned的,对于不变的量应使用const修饰。
// 比如在定义函数的时候,使用的形参类型为常量引用,可以极大的扩展其适用性。比如:形参const string &str可以接收常量版本和非常量版本,而string &str却只能接收非常量版本。其中定义为传引用调用是为了提高效率。 //6.一个返回值类型为void的函数可以使用return返回另一个void类型的函数。 //7.一个重要的规则:不要返回局部对象的引用和指针。在函数内部分配的资源最好在函数内部释放。 //8.函数返回一个指向数组的指针:
int (*fun3())[]; //与fun右边的()是调用运算符其优先级比*高,所以理解方式是:fun3是一个函数,函数返回一个指针类型,指针指向的是一个数组,此数组的维度是10,存储的是int类型的值。
//int *fun3()[10]; //这是错误的声明,理解方式为:fun3是一个函数,函数返回一个数组,数组类型为int*类型且其维度为10。由于函数不能返回数组,所以这是错误的用法。
//使用尾置返回类型可以清晰的声明一个返回指向数组的指针的函数:
auto fun3() ->int (*)[];
//auto fun3() ->int *[10]; //这是错误的,函数不能返回数组类型。
//使用decltype也可以很方便的声明返回一个指向数组的指针的函数。
int a[] = {};
decltype(a) *fun3(); //等价于int (*fun3())[10]; 这里的注意点:decltype作用于数组将得到数组类型,所以声明中的*不能省略
//decltype(a) fun3(); //这是错误的,函数返回数组
int (*fun13(int (*parray)[]))[];//此函数的参数为数组指针,此函数的返回值也是数组指针
char (*(*x[])())[];
//x和[3]结合说明是一个大小为3的数组,该数组的每个元素为一类指针,该类指针指向一类函数,该类函数无参数,返回一类指针,该类指针指向一个大小为5的char型数组 //9.函数的重载:
// main()函数不能重载
// 不允许两个函数除了返回类型外其他所有的要素都相同。
// 一个拥有顶层const的形参无法和另一个不具有顶层const的形参区分开来。
// 在不同的作用域中无法进行函数重载。
// 在C++语言中,名字查找发生在类型检查前。比如:在内层作用域中定义的变量会隐藏外部作用域中的同名函数名字。 //10.关于重载函数匹配:
// 匹配要求有两个:
// 1.该函数每个实参的匹配都不劣于其他可行函数需要的匹配
// 2.至少有一个实参的匹配优于其他可行函数提供的匹配
// 如果不满足上述两个条件,那么函数匹配将出错
// 注意点:
// 1.由于小整形运算将被提升为大整形,所以假如同时提供了void fun(short); void fun(int); 那么调用函数的时候:char x = 10;fun(x);反而会调用void fun(int)的版本。只有当fun参数为short类型的时候才会调用fun(short);
// 2.由于浮点数运算默认以double类型进行,所以如果同时提供了void fun(float); void fun(int);那么调用函数fun(3.14);会造成二义性错误,这是由于所有算数转换的级别都一样
// 3.由于所有算数转换的级别都一样,所以如果同时提供了:void fun(int); void fun(double);那么:unsigned int z = 10; fun(z);将产生二义性错误
// 匹配等级:
// 1.精确匹配:实参类型和形参类型相同。实参从数组类型或函数类型转换为对应的指针类型。向实参添加或删除顶层const属性。
// 2.含有底层const的实参接受对应的无底层const的形参(非常量可以转为常量,但是反之则不行)
int value = ;
const int *pValue = &value;
// 3.通过类型提升(小整数转为大整数类型,有符号整数转为无符号整数等)实现的匹配
// 4.通过算数类型转换或指针转换实行的匹配(常量整数值0或者字面量nullptr能转换为任意类型的指针,以及任意指向非常量的指针向void*的转换和任意指向常量的指针向const void*的转换,以及在有继承关系的类的指针的转换)
// 5.类类型转换实现的匹配 //11.关于默认形参:在给定的作用域中一个形参只能被赋予一次默认实参,通常应该在函数的声明中使用函数默认实参而不是在函数的定义中使用。
// 一个函数可以声明(但是不可以定义)在另一个函数中。局部变量不能作为默认实参。其原因是:用作默认实参的名字在函数声明的作用域内解析,而这些名字的求值发生在函数调用时,这时候的局部变量是未定义的。
void Fun()
{
void Fun1();
Fun1();
}
void Fun1()
{
printf("Fun1\n");//运行至此
}
int _tmain(int argc, _TCHAR* argv[])
{
Fun();
return 0;
}
//12.内联机制用于优化规模小,流程直接,频繁调用的函数。 //13.使用assert预处理宏。assert(expt);若expr为假,则输出信息并终止程序。需包含头文件cassert。使用预处理命令#define NDEBUG (置于cassert之前)可以关闭assert判断。assert语句只在Debug下有效,Release下不会被执行 //14.当我们把函数名当做一个值使用的时候,其会自动转为指针。对函数名解引用即是对函数指针解引用,得到的还是函数类型。
void Fun0(){};
auto temValue = *Fun0; //tenValue是一个函数指针,其等价于: void(*tenValue)();
void (*Fun())(); //Fun是一个函数而不是函数指针,其返回类型是一个函数指针,指向一个返回型为void类型,不接受任何实参的一个函数。
void (*Fun1)() = Fun0; //Fun1是一个函数指针而不是一个函数 //15.函数返回一个指向函数类型的指针:
void fun4();
decltype(&fun4) fun5(); //void (*fun5())()
decltype(fun4)* fun5(); //void (*fun5())()
C++Primer 第六章的更多相关文章
- 【C++ Primer 第六章】 1. 定义模板
类模板 题目描述:实现StrBlob的模板版本. /* Blob.h */ #include<iostream> #include<vector> #include<in ...
- 《C++Primer》第五版习题答案--第六章【学习笔记】
<C++Primer>第五版习题答案--第六章[学习笔记] ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/16 第六章:函数 ...
- C Primer Plus 学习笔记 -- 前六章
记录自己学习C Primer Plus的学习笔记 第一章 C语言高效在于C语言通常是汇编语言才具有的微调控能力设计的一系列内部指令 C不是面向对象编程 编译器把源代码转化成中间代码,链接器把中间代码和 ...
- C primer plus 读书笔记第六章和第七章
这两章的标题是C控制语句:循环以及C控制语句:分支和跳转.之所以一起讲,是因为这两章内容都是讲控制语句. 第六章的第一段示例代码 /* summing.c --对用户输入的整数求和 */ #inclu ...
- 精读《C++ primer》学习笔记(第四至六章)
第四章: 重要知识点: 4.1 基础 函数调用是一种特殊的运算符,它对运算对象的数量没有限制. 重载运算符时可以定义运算对象的类型,返回值类型,但运算对象的个数,运算符的优先级,结合律无法改变. 当一 ...
- C++ Primer Plus学习:第六章
C++入门第六章:分支语句和逻辑运算符 if语句 语法: if (test-condition) statement if else语句 if (test-condition) statement1 ...
- 【C++】《C++ Primer 》第十六章
第十六章 模板与泛型编程 面向对象编程和泛型编程都能处理在编写程序时不知道类型的情况. OOP能处理类型在程序允许之前都未知的情况. 泛型编程在编译时就可以获知类型. 一.定义模板 模板:模板是泛型编 ...
- 【C++】《C++ Primer 》第六章
第六章 函数 一.函数基础 函数定义:包括返回类型.函数名字和0个或者多个形参(parameter)组成的列表和函数体. 调用运算符:调用运算符的形式是一对圆括号 (),作用于一个表达式,该表达式是函 ...
- 精通Web Analytics 2.0 (8) 第六章:使用定性数据解答”为什么“的谜团
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第六章:使用定性数据解答"为什么"的谜团 当我走进一家超市,我不希望员工会认出我或重新为我布置商店. 然而, ...
随机推荐
- Ruby--CSV
1. 解析CSV: (1)读取文件:csv = CSV.read("#{Rails.root}/public/data/statecountycity.csv", :headers ...
- MVC设计模式
随着Web应用的商业逻辑包含逐渐复杂的公式分析计算.决策支持等,使客户机越 来越不堪重负,因此将系统的商业分离出来.单独形成一部分,这样三层结构产生了. 其中‘层’是逻辑上的划分. 三层体系结构是将整 ...
- Java中只有按值传递,没有按引用传递!
今天,我在一本面试书上看到了关于java的一个参数传递的问题: 写道 java中对象作为参数传递给一个方法,到底是值传递,还是引用传递? 我毫无疑问的回答:“引用传递!”,并且还觉得自己对java ...
- 搭建一个Flv视频播放服务器
搭建一个Flv视频播放服务器 热度 15已有 11511 次阅读2009-11-2 22:27 |关键词:服务器 视频 flv 播放 文档 错漏 经过一天的努力,查了好多资料,终于搞定了Flv视频服务 ...
- 对于HIVE架构的理解
1.Hive 能做什么,与 MapReduce 相比优势在哪里 关于hive这个工具,hive学习成本低,入手快,对于熟悉sql语法的人来说,操作简单,熟悉. 2.为什么说 Hive 是 Hadoo ...
- 【Android开发学习笔记】【第三课】Activity和Intent
首先来看一个Activity当中启动另一个Activity,直接上代码说吧: (1)首先要多个Activity,那么首先在res-layout下新建一个 Other.xml,用来充当第二个Activi ...
- cdecl和stdcall调用约定-汇编演示
. .model flat, stdcall .stack ExitProcess PROTO, dwExitCode:DWORD .data val2 sdword result dword ? . ...
- 如何解决jQuery Validation针对动态添加的表单无法工作的问题?
为了充分利用ASP.NET MVC在服务端呈现HTML的能力,在<利用动态注入HTML的方式来设计复杂页面>一文中介绍了,通过Ajax调用获取HTML来呈现复杂页面中某一部分界面的解决方案 ...
- java构造函数,java的静态块理解
今天我遇到这样的代码块,理解甚久,现在理解了,举一些例题给你看看 先创建一个One类: package accp.com;/** * 其中一个类 * @author xuxiaohua * */pub ...
- [LeetCode]题解(python):088 Merge Sorted Array
题目来源 https://leetcode.com/problems/merge-sorted-array/ Given two sorted integer arrays nums1 and num ...