C++编程知识快速复习(中)(精华高效全面版)

 

1.栈存储与堆存储的区别

    C++程序编译占用的内存可以分为以下几个部分:

    栈区:由编译器自动分配释放,存放函数的参数值、局部变量等,用于存放占用空间小、生命周期短的数据

    堆区:由用户分配释放,用于存储占用空间大、生命周期长的数据,如静态变量和全局变量。手动分配空间后一定要释放空间,否则会导致内存泄漏;

    全局区:全局变量和静态变量是存储于在一起的,初始化的存储一块区域,未初始化的存储相邻区域;

    文字常量区:常量字符串存放于此区,程序结束后由系统释放;

    程序代码区:存放函数体的二进制代码;

堆与栈的区别可以分为三个方面:

 

  • 堆栈在空间上的区别见上面;
  • 堆栈在缓存方式上的区别:栈使用的是一级缓存,通常都是被调用时处于存储空间,调用完成立即释放;堆是存放在二级缓存中的,生命周期由虚拟机的垃圾回收算法来决定,故调用这些对象的速度相对较慢;
  • 堆栈在数据结构上的区别:堆数据结构可以看成是一棵树,如堆排序;栈数据结构是一种先进后出的数据结构;

逗号表达式:它的运算优先级最低,逗号表达式取最右边表达式的值。

const与define的比较:

    C++语言可以使用这两者来定义常量,但是使用const更好,理由如下:

 

  • const常量有数据类型,而宏常量没有数据类型,编译器可以对前者进行安全检查,而对后者只能进行字符替换,字符替换可能会发生意想不到的错误;
  • 有些集成化调试工具可以对const常量进行调试,但不能对宏常量调试,此时只能使用const定义常量。更精确地说,const在程序运行时只有一份复制品,而define有多份复制品

2.类中的常量问题

    在类中定义常量,我们很自然地想到使用const,但是const数据成员只对某个对象生存周期内是常量,而对整个类而言是可变的,因为创建多个对象时,不同对象其const数据成员的值可以不同。不能在类声明中初始化const成员,其初始化只能在类的构造函数初始化列表中进行。因为类未被创建时,编译器不知道相应的常量是什么。

    应该使用枚举常量来在类中建立一个恒定的常量,枚举常量不会占用对象的存储空间,在编译时全部求值。

3.C++相关语句

    C++语句一般由表达式和分号构成的,只有空分号的语句为空语句,程序中允许有多条空语句,空语句不执行任何功能。{}是复合语句,也可用复合语句来代替空语句,但是括号后面没有分号。

    多条if语句,程序会依次执行各条语句,从而条件判断较为复杂。对于if/else语句,程序只选择一个分支按条件执行。

    return语句用来退出当前函数的执行,若函数没有返回值,则只使用return语句,后不加任何表达式。在使用return语句时,要注意如果代码之前在堆中分配了内存,则在return语句前要释放内存,以防止内存泄漏。

    exit语句用于终止当前进程,通常用于结束当前的应用程序。exit包含一个整型参数,用于标识退出的代码,与return不同的是,return语句只退出当前调用的函数,除非当前函数是主函数,return会结束当前进程,而exit会直接结束当前进程,无论当前函数是否是应用程序的主函数。

4.C++函数相关

 

  • 在定义函数时,若函数返回类型不是void类型,一定要在函数中加入return语句;
  • 若调用函数处于被调用函数下方,则要对被调用函数进行前置声明,声明也可放置于main函数内部
  • 若函数有多个参数,应保证默认参数出现在参数列表的最右方。
  • 在定义数组参数、函数参数时,也可不指定数组的大小,在调用C++编译器时不对数组长度进行检查,只是将数组首地址传给函数,但是使用数组的引用会强制检查参数中元素的个数,这可以更好地确定程序的安全。

    值传递:在函数调用时,将实际参数的值复制一份传递到调用函数中,实际参数值不受影响;

    引用传递:即传址调用,按引用传递时,调用函数修改了参数值,实际参数值也会发生改变。

    因此,通常在定义函数时,如果参数为数组、指针或引用类型,则用引用类型传递方式,否则用值传递方式。

内联函数:

    内联函数是指对于程序中出现函数调用的地方,如果是内联函数,编译器直接将函数代码复制到函数调用的地方,省去了程序跳转的过程,用inline关键字标识内联函数。内联函数的目的是提高程序的执行效率

    对于使用inline关键字的内联函数,程序不一定将函数作为内联函数对待,这关键取决于编译器的优先机制。通常对于代码较少、频繁调用的函数,可以标识为内联函数,否则不使用内联函数。

函数的重载:

    重载是多个函数具有相同的函数名称,而参数类型或参数个数不同,在调用时编译器正是通过参数类型和参数个数来区分调用哪个函数。

    返回值不作为区分重载的一部分;对于参数来说,const关键字不作为区分,但若参数是指针或引用类型,const作为区分标志;参数默认值不作为区分标志;

注意:在局部域中定义声明函数,将使同名函数隐藏而不是重载,要访问其他域函数,用::域访问符。

函数指针:

    在C++语言中,函数名实际上是指向函数的指针,定义有如下几种形式:

    对于函数指针来说,它指向的函数必须与函数指针定义的形式相同,即返回类型、参数、参数个数均相同。在程序中使用函数指针可以极大的丰富程序的灵活性。

5.局部作用域和全局作用域

    局部作用域描述的是函数体中变量、常量等对象的作用范围,对于处于同一个作用域的对象来说,对象不允许重名。当编译器在当前代码处发现变量名时,它将在当前局部作用域中搜索变量的定义,如果未定义则向外搜索,直到局部作用域完成;

    全局作用域是函数、变量、常量对象作用范围是整个应用程序。对于全局变量,若未初始化,其存储区为0,对于局部变量,若未初始化,则其值是不可预见的。

6.定义和使用命名空间

    在一个应用程序中的多个文件可能存在同名的全局对象,这样会导致应用程序的链接错误,使用命名空间是消除命名冲突的最佳方式。命名空间的定义格式如下:

    若要使用命名空间中的对象,则要在对象前加上命名空间的名字,若要访问命名空间的多个对象,可以使用using命令,using的作用域是从当前引用处到当前作用域结束。

    对于同一个命名空间,可以在多个文件中定义,此时命名空间中的内容是各个文件中内容之和。命名空间也可嵌套,访问内层函数时,可以用using namespace 外层名称::内层名称

    using命令用于引用命名空间中的全部空间对象,容易和正在编写的程序中的局部变量发生冲突,导致命名空间的变量被隐藏,故不建议过多使用此命令。不命名的空间中的对象只适用于当前文件,各文件中不能相互访问,在一个文件中访问空间中的对象与访问普通全局对象是相同的。

7.函数模板

函数模板提供了一种机制,使函数返回值、参数类型能够被参数化,而函数体保持不变,这极大的增强了函数的灵活性。定义格式如下:

函数模板也可以重载,要注意区分。

 

=========================================

本文到此结束!

如果对你有帮助,请随手 点赞 或 赞赏

欢迎关注、私信、交流,一起学习,一起进步!

==========================================

 

 

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

huixieqingchun

钟意作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值