
C 核心特性详解目录6. 引用概念和定义小试牛刀引用的作用const引用引用和指针的关系7. 宏函数8. inline 内联函数9. nullptr6.引用这是C入门部分最大的一个重点也是改进 C语言最大的一个特点概念和定义引用不是新定义一个变量而是给已经存在的变量取别名编译器不会为引用变量开辟内存空间它和它引用的变量共同用一块内存空间类型 引用别名 引用对象引用的特性• 引用在定义时必须初始化• 一个变量可以有多个引用• 引用一旦引用一个实体再不能引用其他实体小试牛刀cout 自动识别类型a是取地址int*类型按照地址打印b是引用运行结果显示出二者的地址是相同的这也反向印证了引用没有开辟新空间就是给变量取别名在这里让b我们同时打印发现a和b同时加了1那一个变量能否取多个别名呢是可以的下面我们看到不管添加多少变量打印出来的地址都是相同的引用是不会改变指向的这里c是a的别名那就一直都是a的别名不会把x赋值给c所以这里是把x赋值修改c引用的作用引⽤和指针在实践中相辅相成功能有重叠性但是各有特点互相不可替代。C的引⽤跟其他语⾔的引⽤(如Java)是有很⼤的区别的除了⽤法最⼤的点C引用定义后不能改变指向Java的引用可以改变指向。引用功能1做函数形参修改形参影响实参引用功能2做函数形参减少拷贝提高效率引用功能3引用做返回值类型修改返回对象引用功能4引用做返回值类型减少拷贝提高效率不用传地址直接引用实参修改形参的同时实参也改变直接引用结构体就不再申请空间拷贝结构体①返回ret时函数内存已经销毁②xxx会非法访问原来已经释放的空间导致x值的变化引用不能改变指向所以在链式结构中无法替代指针这些场景必须使用指针Java中只有引用没有指针这里的引用可以改变指向const引用•①可以引⽤⼀个const对象但是必须⽤const引⽤。const引⽤也可以引⽤普通对象因为对象的访问权限在引⽤过程中可以缩⼩但是不能放⼤。②不需要注意的是类似 int rb a3; double d 12.34; int rd d; 这样⼀些场景下a3的和结果保存在⼀个临时对象中 int rd d 也是类似在类型转换中会产⽣临时对象存储中间值也就是时rb和rd引⽤的都是临时对象⽽C规定临时对象具有常性所以这⾥就触发了权限放⼤必须要⽤常引⽤才可以。③所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象C中把这个未命名对象叫做临时对象。权限不能放大权限可以缩小指针和引用才涉及到权限的放大和缩小引用和指针的关系C中指针和引用就像两个性格迥异的亲兄弟指针是哥哥引用是弟弟在实践中他们相辅相成功能有重叠性但是各有自己的特点互相不可替代。- 语法概念上引用是一个变量的取别名不开空间指针是存储一个变量地址要开空间。- 引用在定义时必须初始化指针建议初始化但是语法上不是必须的。- 引用在初始化时引用一个对象后就不能再引用其他对象;而指针可以在不断地改变指向对象。- 引用可以直接访问指向对象指针需要解引用才是访问指向对象。- sizeof中含义不同引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32位平台下占4个字节64位下是8byte)- 指针很容易出现空指针和野指针的问题引用很少出现引用使用起来相对更安全一些。7.宏函数宏是一种替换缺点复杂 / 类型安全检查 / 不能调试优点预处理阶段战替换不用建立栈帧本质是一种提效8.inline 内联函数1.⽤inline修饰的函数叫做内联函数编译时C编译器会在调⽤的地⽅展开内联函数这样调⽤内联函数就需要建⽴栈帧了就可以提⾼效率。2.inline对于编译器⽽⾔只是⼀个建议也就是说你加了inline编译器也可以选择在调⽤的地⽅不展开不同编译器关于inline什么情况展开各不相同因为C标准没有规定这个。inline适⽤于频繁调⽤的短小函数对于递归函数代码相对多⼀些的函数加上inline也会被编译器忽略。3.C语⾔实现宏函数也会在预处理时替换展开但是宏函数实现很复杂很容易出错的且不⽅便调试C设计了inline⽬的就是替代C的宏函数。4.vs编译器 debug版本下⾯默认是不展开inline的这样⽅便调试debug版本想展开需要设置⼀下以下两个地⽅。5.inline不建议声明和定义分离到两个⽂件分离会导致链接错误。因为inline被展开就没有函数地址链接时会出现报错。9.nullptrNULL实际是⼀个宏在传统的C头⽂件(stddef.h)中可以看到如下代码#ifndefNULL#ifdef__cplusplus#defineNULL0#else#defineNULL((void*)0)#endif#endif1.C中NULL可能被定义为字⾯常量0或者C中被定义为⽆类型指针(void*)的常量。不论采取何种定义在使⽤空值的指针时都不可避免的会遇到⼀些⿇烦本想通过f(NULL)调⽤指针版本的f(int*)函数但是由于NULL被定义成0调⽤了f(int x)因此与程序的初衷相悖。f((void*)NULL);调⽤会报错。2.C11中引⼊nullptrnullptr是⼀个特殊的关键字nullptr是⼀种特殊类型的字⾯量它可以转换成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题因为nullptr只能被隐式地转换为指针类型⽽不能被转换为整数类型。