一、掌握形参带默认值的函数

  1. 给定默认值的时候是从右向左给,因为函数在内存中的压栈顺序是按照形参列表的元素从右向左依次向内存中压栈
  2. 形参是否有默认值对调用效率的问题:如果有一个默认值,在函数调用的过程中会少一条mov指令,多个默认值就是减少了多条指令。如果调用的时候用的是立即数,也会减少mov指令,因为在访问变量的时候会用到mov指令。
  3. 定义处可以给定形参默认值,声明处也可以给定形参默认值
  4. 给定形参默认值的时候,不管是定义处给还是声明处给,一个形参的默认值只能出现一次。

sum函数为例:

int sum(int a=10,int b=0);//在声明处可以给定默认值
//当然前提是定义出没有给定默认值。

二、掌握inline函数

inline函数和普通函数逇区别:

  • 在编译的过程中,没有函数调用的开销(少了call和push等操作),会直接在函数的调用点吧函数的代码展开处理。
  • 同时inline函数不会在.ojb文件的符号表中生成相应的函数符号
  • inline关键字只是建议编译器把这个函数处理成内联函数,但不是所有的inline声明都会被编译器处理为内联函数
  • debug中的inline是不起作用的,因为要方便调试

标准的函数调用过程为:参数压栈。函数栈帧的开辟和回退过程,如果函数作用很简单,会导致函数开销大于函数执行消耗的时间

三、函数重载详解

首先是三个关于函数重载的问题:

  1. c++为什么支持函数重载?,为什c语言不支持函数重载?

    因为c++代码在编译时产生函数符号的时候是用函数名+参数列表类型组成的,如sum_int_int,而c代码产生函数符号的时候只使用函数名表示。

  2. 函数重载需要注意什么?

    • 有不同形参列表的函数要放在同一个作用域中才会发生函数重载,包括定义和声明,在一个作用域中定义了多个函数,在另一个作用域中声明了一个函数,会有限使用更小的作用域中的定义或者声明。
    • 同样类型的形参列表加不加const表示一个函数,不会进行函数重载;同时返回值不同但是形参相同的函数也不会进行函数重载,因为函数符号是使用函数名和参数列表类型组成的,没有记录返回类型。
  3. C++和c代码之间如何相互调用?

    1. c调用c++:在c++源码括在extern “C”{}中,即:

      extern "C"{
      int sum(int a,int b){
      return a+b;
      }
      }
    2. c++调用C代码:把c函数的声明括在extern ”C”中

      extern "C"{
      int sum(int a,int b);
      }

如果是写跨语言的代码,一般会写成一下形式:

#ifdef __cplusplus
extern "C"{
#endif
int sum(int a,int b){
return a+b;
}
#ifdef __cplusplus
}
#endif

这样写在跨语言的时候会非常方便,因为__cplusplus宏只在cpp代码中有。如果是c的代码就不会使用extern“C”语法,如果是c++代码,则会注意编译的时候是不是以C的形式编译。

四、全面掌握const的用法

两个问题:

  1. 要怎么理解const?

    • const修饰的变量不能再作为左值,初始化完成后值不能被修改。

    • c++中的const必须初始化,初始化的时候如果用的是立即数,叫做常量,可以用来定义数组的长度;如果初始化的时候用的是变量赋值,因为变量的值只有在运行的时候才会知道,所以此时const修饰的值叫做常变量,此时就不能定义数组的长度了。

  2. C和C++中const的区别是什么?

    • 两者的编译方式不同,C中的const是当做一个变量来编译生成指令的;而c++在编译过程中所有出现const常量名字的地方,都被常量的初始化替换了,如果初始化时用的是变量则与c中的编译方式相同。

以下是const的一个例子:

int main(){
const int a=20;
int *p=(int*) &a;
*p=30; cout<<a<<" "<<*p<<" "<<*(&a)<<endl;//
//输出的分别是20 30 20
//如果是常变量,即只是不能作为左值,输出的变量就为30 30 30
}

因为const在编译的时候就会把所有的出现const值的位置都设置为初始值,所以上面代码中所有的a都是初始值20,但是仍然可以改变内存中的值,所以*p中的值为30。

五、掌握const和一二级指针的结合应用

const修饰的量常出现的错误是:

  1. 常量不能再作为左值 《= 直接修改常量的值
  2. 不能把常量的地址泄露给一个普通的指针或者普通的引用变量 《= 可以间接修改常量的值

const和一级指针结合的例子:

在C++规范中,const修饰的是离他最近的类型;

如果const的右边没有指针的话,const是不参与类型的。下面列举四种一级指针与const结合的例子:

  • const int *p

    int a = 19;
    const int* p = &a;//const修饰的表达式是*p,*p不能被赋值,但是可以修改p的内容
    //可以指向任意int类型的内存,但是不能通过指针间接修改指向内存中的值
    p = &b;

    const修饰的表达式是p,p不能被赋值,但是可以修改p的内容可以指向任意int类型的内存,但是不能通过指针间接修改指向内存中的值.p的类型是int const *

  • int const* p

    int const* p = &a;//const修饰的表达式是*p与上面的情况一致

    p的类型是int const *

  • int *const p

    int* const p = &a;//p的类型是int* const,const修饰的表达式是p,就是说p不能被赋值,*p可以
    *p = b;//p不能再指向别的内存,但是可以通过指针解引用修改内存中的值

    p的类型是int*

  • const int *const* p

    const int* const p=&a;//上面两种情况的结合,p和*p都不能被改变、

    p的类型是int const *

const和二级指针结合的例子:

  • int const** pconst修饰的是**p,其值不能改变
  • int *const* pconst修饰的是*p,其值不能改变
  • int **const pconst修饰的是p,其值不能改变,但是能改变**p和*p的值

总结const和一级指针、二级指针的类型转换公式:

类型转换 是否正确
int* <- const int* 错误
const int* <- int* 正确
int** <- const int** 错误
const int** <- int** 错误
int ** <- int *const* 错误
int *const* <- int ** 正确

int *const* <- int **:可以看做是*->const*,因为const修饰的是后面的*。

二级指针两边必须都有const才能成立

例题

A错 第三句 int const *->int*错误

B对 int* -> int*

C对 int* -> int*

D对 int* -> int const*

A错 const int** <- int**

B对 int const* <- int*

C对 int** <- int**

D错 int *const* -> int**

E对 int *const* <- const int**

六、掌握c++的左值引用、初识右值引用

用指针引用数组:

int array[5]={ };
int *p=array;
//定义一个引用变量来引用数组array
int (&q)[5]=array; cout<<sizeof(array);//20
cout<<sizeof(p);//4
cout<<sizeof(q);//20

七、const,一级指针,引用的结合应用

判断题:

A:正确 把引用还原为指针,最后一句就可一写为:int **q=&p;两边都是int的二级指针

B:错误 不能把一个const的内存泄露给一个普通的指针

C:错误 const int**->int**

D:错误 原因如下:

引用和指针一样,如果遇到不清楚的就把引用换成指针。

八、深入理解C++的newdelete

new和malloc的区别?

delete和free的区别?

而new只需要一句就能做上面的操作:int *p=new int(20);

开辟数组的不同:

一些常识:

new有多少种?

总共四种:

最后一种定位new是在指定位置开辟内存。

二、深入学习c++需要掌握的基础知识的更多相关文章

  1. 第十二章 学习 shell脚本之前的基础知识

    http://www.92csz.com/study/linux/12.htm [什么是shell] 简单点理解,就是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具.实际上,在shell和 ...

  2. 学习 shell脚本之前的基础知识

    转载自:http://www.92csz.com/study/linux/12.htm  学习 shell脚本之前的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写sh ...

  3. java中文乱码解决之道(二)-----字符编码详解:基础知识 + ASCII + GB**

    在上篇博文(java中文乱码解决之道(一)-----认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述字符集.字符编码等基础知识和ASCII.GB的详情. 一.基 ...

  4. java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**

    原文出处:http://cmsblogs.com/?p=1412 在上篇博文(java中文乱码解决之道(一)—–认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述 ...

  5. 学习shell脚本之前的基础知识

    日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写shell脚本,那么你就不算一个合格的管理员.目前很多单位在招聘linux系统管理员时,shell脚本的编写是必考的项目.有的单位 ...

  6. 大数据学习笔记——Java篇之基础知识

    Java / 计算机基础知识整理 在进行知识梳理同时也是个人的第一篇技术博客之前,首先祝贺一下,经历了一年左右的学习,从完完全全的计算机小白,现在终于可以做一些产出了!可以说也是颇为感慨,个人认为,学 ...

  7. 2.Docker容器学习之新生入门必备基础知识

    0x02 Docker 核心概念 描述:Docker的三大核心概念镜像/容器和仓库, 通过三大对象核心概念所构建的高效工作流程; 1.镜像 [image] 描述:images 类似于虚拟机镜像,借鉴了 ...

  8. SQL学习(一)相关基础知识

    RDBMS基础知识 1.数据库是按照数据结构来组织.存储和管理数据的仓库:数据库是一些关联表的集合. 2.数据表是数据的矩阵,在一个数据库中的表看起来像一个简单的电子表格. 3.列:一列包含了相同的数 ...

  9. (数据科学学习手札45)Scala基础知识

    一.简介 由于Spark主要是由Scala编写的,虽然Python和R也各自有对Spark的支撑包,但支持程度远不及Scala,所以要想更好的学习Spark,就必须熟练掌握Scala编程语言,Scal ...

随机推荐

  1. spring @Bean和@Order 官方doc理解

    今天阅读了spring的官方代码,(大概)理解了@Bean和@Order如何使用. @Bean 官方代码解读: 0.@Bean的注入,用于表示这个bean被spring容器管理(创建.销毁)(官方英文 ...

  2. ElasticSearch-学习笔记01-docker安装

    安装ElasticSearch docker 安装请参考: https://www.cnblogs.com/youxiu326/p/docker-01.html docker run -d --nam ...

  3. 数仓建模—OneID

    今天是我在上海租房的小区被封的第三天,由于我的大意,没有屯吃的,外卖今天完全点不到了,中午的时候我找到了一包快过期的肉松饼,才补充了1000焦耳的能量.但是中午去做核酸的时候,我感觉走路有点不稳,我看 ...

  4. 【Android开发】【数据库】LitePal 数据库的使用

    一,导包 dependencies { ...... // LitePal的包 compile 'org.litepal.android:core:1.3.1' ...... } 二,创建bean类 ...

  5. java中“类”和“对象”到底有什么联系

    4.object和Class配合工作原理    [新手可忽略不影响继续学习] Class是"类"的意思,是抽象的,并没有具体的说是哪个东西.而object是具体的,实实在在存在的一 ...

  6. java基础-多线程-线程组

    线程组 * Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制. * 默认情况下,所有的线程都属于主线程组.  * public fi ...

  7. javascript回调地狱真的只能Promise来解决吗?js回调地狱,Promise。

    javascript的灵活在于函数可以当作函数的参数来传递,以及它的异步回调思想.但是这就带了一个很严重的问题,那就是回调次数过多,会影响代码结构,多层嵌套影响代码的可阅读性,也不便于书写. 举个例子 ...

  8. c++对c的拓展_增强

    一:新增bool类型关键字:c中bool类型需要添加stdbool.h头文件,c++则可直接使用 void test(){ bool a=true; //c++可直接定义而c需添加头文件 true和f ...

  9. spring-注入list集合对象(值是对象)

    1.创建stu类 public class Stu { // //1.数组类型 // private String[] courses; // // //2.list集合属性 // private L ...

  10. JDK1.8.0_181的无限制强度加密策略文件变动(转载)

    JDK1.8.0_181的无限制强度加密策略文件变动 原文地址 https://my.oschina.net/my1313677/blog/3109613 作者 葉者 日常记录 2019/09/23 ...