• C++入门


    前言:

    本文主要讲解C++解决了C语言哪些语法的不足,C++是如何改进的。

    一、命名空间

    C语言中,会遇到两种情况的命名冲突,分别是

    1. 我们写的变量名称和库冲突
    2. 我们互相冲突

    注意C语言无法解决命名冲突的问题。

    C++解决方法:
    运用命名空间关键字:namespace

    下面的代码表示rand变量与库函数stdlib中的rand函数命名冲突,我们运用namespace命名空间。

    相当于在rand = 0围上了一圈栅栏,默认不访问栅栏里面的内容,从其他全局域寻找

    当我们使用::域作用限定符,相当于钥匙打开了栅栏,我们就从栅栏里面的内容寻找。

    1. #include
    2. #include
    3. namespace wh
    4. {
    5. int rand = 0;//rand还是全局变量
    6. }
    7. int main()
    8. {
    9. printf("%p", rand);//表示rand这个函数
    10. printf("%d", wh::rand);//::域作用限定符,表示我们自己定义的rand变量
    11. return 0;
    12. }

    我们平时定义的所有变量都可以在命名空间中定义,注意结构体语法形式有点不同

    命名空间可以套娃!

    命名空间在多个文件中可以合并,所以不必考虑多个相同的命名空间回重复。

    但有时命名空间也是累赘,比如自己写好做测试,没有给别人用,不存在命名冲突,我们每次调用变量、函数都需要加上命名空间吗?

    就需要展开命名空间,这样每次调用就不用加上命名空间。

    所以我们就理解了

    using namespace std

    这是C++官方库定义的命名空间,里面包含了cout、cin等等。

    工程项目不要展开std,容易冲突。

    但是日常练习,为了方便就可以展开

    命名空间的另一种玩法:

    每次指定命名空间很不方便,直接展开全部暴露,又有命名冲突的风险

    我们采用指定展开可以解决问题。

    二、缺省参数:(舔狗)

    缺省参数是声明或定义函数时为函数参数指定一个缺省值

    在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

    我们做人不能做缺省参数(舔狗),女神没有对象时请你看电影,用缺省参数,但如果有对象,直接就不用你了,用自己的参数,不用缺省参数。

    缺省参数分类:

    全缺省参数:

    函数中的所有参数都带有缺省值,在调用时不能隔着传参。

    半缺省参数:

    函数中参数并不完全带有缺省值。

    注意:
    • 半缺省参数必须从右到左依次来给出,不能间隔着给。
    • 缺省参数不能在函数声明和定义同时出现。害怕两者缺省参数不同。只能在声明函数中给

    三、函数重载

    C语言不支持同名函数。

    是函数的一种特殊情况,C++允许在同一作用域中声明几个功能相似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或类型顺序)不同,返回值无关

    为什么与返回值无关?

    因为当你调用两个返回值不同的重载的函数,如果参数都相同,不能根据返回的不同确定到底调用哪个函数。

    为什么C++支持函数重载,C语言不支持呢?

    C语言链接函数地址时,就用函数名去寻找,所以C语言不存在同名函数。

     但在C++中,运用了函数名修改规则

    _Z 函数名字符个数 函数名 参数首字母

    当函数只有声明,没有定义,会在链接时候报错,链接的意义是链接一些没有确定函数地址

    四、引用:

    引用不是新定义一个变量,而是给已存在变量取了一个别名,引用的变量和本身变量共用同一块空间引用就是取别名。 

    引用的价值:

    1、传参数

    经典例子,在单链表中尾插,如果链表为空,需要改变头节点,这时候就要用到二级指针去改变正在指向的内容,但如果引用结点指针的变量,不需要指针即可。

    疑问:在C++中,可不可以让引用替代指针?

    答案肯定是不可以。

    引用的注意点:

    1、引用必须初始化。

    2、C语言引用不能改变指向。 

    上述代码表示d赋值给c,c是a的别名,c = d表示赋值,不是变成d的别名,因为在C语言中引用不能改变指向

    这也就验证了C++中,引用不能替代指针,在Java语言中,引用是可以改变指向的,所以在链表中,如果用引用表示next指针,Java可以改变指向,指向另一个结点,在C++中就不行,因此C++中引用和指针是相互配合的关系

    3、一个对象可以有多个别名

    2、做返回值

    补充知识点:C语言传值返回的机制

    上面count函数返回值是n吗?

    不是,返回值是n的拷贝。

    为何?

    因为函数栈帧在调用后回自动销毁,所以count函数会自动销毁,n也会销毁,所以我们返回的是n的拷贝,不属于count函数空间里面的内存

    如果是传引用返回,打印的结果是不确定

    因为返回引用n就是n的别名,也就是n本身,为何不确定,因为不确定编译器在count调用后(栈帧结束)是否清理空间,如果空间不清理,就是n,如果清理了就是随机值。

    那传引用返回有什么用武之地呢?

    引用返回和静态变量结合,(出函数作用域不会销毁的变量,不是在栈空间上创建的变量)。

    ret就是c的别名,两者相同

    输出结果是3,3

    为何不是3,7?

    因为局部的静态变量只会初始化一次

    这样的输出结果就是3,7!

    引用返回的价值:

    第一个价值:提高效率

    传值返回时,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回类型,效率是非常地下的,尤其是当参数或者返回值类型非常大时,效率就更低。

    第二个价值:可以修改返回值

    引用返回的总结:

    出了函数作用域,返回对象就销毁了,不能用引用返回,否则结果是不确定的。只有返回值在出函数作用域之后还在,才能用引用返回!

    指针和引用的区别:

    在使用上和概念上的区别

    在语法上,引用没有开辟空间,但是指针开辟空间

    在底层汇编语言上。两者原理是一样的。

    五、内联函数:

    因为在C语言中,宏的缺点太多!

    宏本质上是替换!

    1. #define Add(x,y) ((x) + (y))//容易出错
    2. int main()
    3. {
    4. int sum = Add(3, 2);
    5. printf("%d", sum);
    6. return 0;
    7. }

    注意宏每个括号的含义,应对运算符优先级的问题。并且不能有;,因为宏是表达式的替换

    宏函数的缺点:

    1. 容易出错,语法细节多
    2. 不能调试
    3. 没有类型的安全检查

    宏函数的优点:

    不用建立栈帧,提升程序运行的效率。普通函数使用时,需要建立栈帧,而栈帧的建立是非常繁琐的。

    因为宏函数缺点较多,所以C++在此基础上应运而生了内联函数。

    内联函数概念:

    以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

    内联函数的优点不仅包含了宏函数的缺点,还不用创建栈帧,如此优秀的机制,

    那为什么不把所有函数都变成内联函数呢?

    内联函数只适用于函数代码量较小的情况下(低于10行)。

    因为如果函数调用次数过多,每次都要展开,会使得程序量变大(很坏)

    而普通的函数调用只需要一行调用指令即可。

    注意内联函数不能声明和定义分离(不能在一个文件定义,在另一个文件声明),

    因为内联函数被展开,就没有函数地址了,链接就会找不到。

  • 相关阅读:
    Servlet快速入门
    Day 54 多线程
    【分隔结构】定从分离
    阿里面试官浅聊Java面试那些事
    AQS详解
    图扑软件荣获第七届“创客中国”中小企业创新创业大赛优胜奖!
    idea 打 jar 包以及运行使用
    深入探索 Django Rest Framework
    1456.定长子串中元音的最大数目
    素问·热论原文
  • 原文地址:https://blog.csdn.net/hanwangyyds/article/details/133886804