• 【C++入门】C语言的不足之处


    概要

    C++入门主要讲的是C语言的一些不足,C++作为补充,来补充C的不足之处

    C++的关键字有63个,C语言有32个(作为了解,不需要专门记)

    变量的命名规则:

    1. 变量名必须以字母或下划线开头。
    2. 变量名只能包含字母、数字和下划线。不允许使用其他特殊字符。
    3. 不能与关键字重名

    C语言中有命名冲突的问题(与库函数,或者工程里的其他变量/函数名发生冲突),因此就引出了命名空间的概念。

    ps:前面的文章有专门讲过命名空间,这里就不再重复介绍辣,可以去翻翻之前的文章

    输入输出

    istream   输入流

    ostream  输出流

    而C++中常用到的cin和cout就分别是istream和ostream的对象

    cin    >>  流提取运算符  输入

    cout  <<  流插入运算符  输出

    cout 可以自动识别类型(但是是基于函数重载基础上的,后面会说到函数重载)

    类库提供的头文件中已经对“<<”和“>>”进行了重载,使之作为流插入运算符和流提取运算符,能用来输出和输入C++标准类型的数据。

    本质是在补充C语言的不足 对全局的变量,函数,类型进行封装,防止引发冲突

    也可以去库函数中查询相关资料

    C++官网:en.cppreference.com/w/

    C++的输入输出比scanf/ printf要慢一点点 why?

    因为:C++会同步C语言,会检查C语言的错误,如果希望快一点,可以选择关闭同步C语言或者使用scanf / printf

    缺省参数(默认参数)

    注意:

    1)传参是从左往右传参, 缺省是从右向左缺省

    2)缺省参数应该在声明的时候给缺省值,定义给缺省值没有实际意义,这样在传参的时候会转化到对应参数个数

    3)必须是常量或者全局变量

    1】全缺省:会用缺省值来初始化

    如果给了参数则用参数值来初始化 

    2】半缺省:从右向左缺省

    函数重载

    同一作用域 形参(参数个数 类型 类型的顺序)不同 只有返回值不同是不行的

    无参调用存在歧义 调用0个的时候存在歧义

    为什么C++支持函数重载? 答:与函数名修饰规则有关 以及 编译链接过程有关

    三个文件:Stack.h Stack.c test.c

    预处理 头文件展开 宏替换 去除注释 条件编译 .i    最后生成Stack.i test.i

    编译 语法检查 生成对应汇编代码 .s                      最后生成 Stack.s test.s

    汇编   xor(逻辑异或)  cpu是不认识汇编代码的,只识别二进制。需要把汇编代码转换成二进制机器码 .o目标文件                                                                    最后生成 Stack.o test.o

    链接 可执行程序 .exe /a.out(不指定) 此过程中 才会去看会不会重命名(找到定义 兑现承诺) 头文件中声明代表承诺 链接的过程就是一个兑现承诺的过程

    error:无法解析外部符号 链接错误

    一般都是缺少定义(有声明无定义) ,声明和定义不能同时赋值(缺省值),只能在声明中给缺省值,相当于将缺省参数补全了

    因此C++支持函数重载而C语言不支持的原因在于:

    1、C语言同名编译阶段就会报错 因为同名函数编译器不知道找哪一个

    2、C++ 编译链接 g++将函数名和参数的数据类型缩写写入

    windows下名称修饰规则:

    所有函数都要链接吗?

    如果在当前文件就有定义的话 编译阶段直接(兑现承诺),不需要进行链接操作,

    因为编译的时候给了定义,相当于直接兑现承诺,就不需要进行链接了。

    引用

    给已存变量取别名,与被引用的变量公用一块命名空间

    给引用变量赋值相当于给被引用变量赋值

    引用的价值?

    一个变量可以有多个引用,但是引用一旦有一个实体就不能引用其他实体了

    引用在定义的时候必须初始化

    就是取别名,认为没有开辟新的空间

    注意:

    1.定义时就必须初始化

    2.一个变量可以有多个引用

    3.但是引用一旦对应一个实体,就不能改变指向了

    用引用的好处在于:

    1、做参数

    a、做输出型参数

    输出型参数是指 形参改变会影响实参 就像swap函数用引用类型做形参,会改变实参

    b、减少拷贝,提高效率

    2、做返回值

    a、减少拷贝,提高效率

    做返回值的时候,因为出作用域变量会销毁,所以会建立一个临时变量;但是当变量不销毁(在静态区)的时候,也会建立临时变量(会不会生成临时变量,看的并不是变量出了函数会不会销毁,而是返回值类型;如果是传值返回,都会进行拷贝生成临时变量,如何不生成临时变量?)可以用引用类型作为返回值不生成临时变量,可以减少拷贝,提高运行效率

    如果引用作为返回值,不需要拷贝,但是如果变量销毁了,返回的结果就不能确定了

    可能情况:a、函数调用结束,函数栈帧销毁,未清理函数栈帧,结果是对的

                      b、函数调用结束,函数栈帧销毁,清理了函数栈帧,结果是错的

    所以说一定要保证出了函数,变量不会销毁(仍然存在),才可以返回引用

    b、获取返回值 修改返回值

    可以用引用实现SLAt()函数,同时实现SLGet()和SLModify()的功能,简化代码

    引用权限

    引用权限不可以放大,但是可以缩小/平移

    1. const int a;
    2. int& b=a;
    3. //权限放大了,改变b a也会改变 但是a本身是不能被改变的
    4. int a=10;
    5. int& b=a;
    6. //权限平移了,可以这么写
    7. int m=10;
    8. int& n=m;
    9. const int& p=m;
    10. //权限缩小了。可以这么写
    11. //不能通过p来改变m,但是m本身是可以修改的
    12. m++;//可以这么写
    13. n++;
    14. //m和n变了之后p也变了

    临时变量创建场景

    1】带返回值的普通函数,调用结束的时候会建立栈帧,建立临时变量

    2】在发生类型转换的时候会创建临时变量相同类型不会产生临时变量)

    1. double a=1.0;
    2. int b=a;//a发生类型转换,(截断或提升的时候)先创建临时变量
    3. if(a>b)//比较的类型不同,会发生类型提升(一般是小的向大的提升)
    4. { //先生成临时变量
    5. swap(&a,&b);
    6. }

    引用与指针区别?

    【1】从语法层面上看:

    引用:不开空间,只是对变量取别名

    指针:开空间,开辟空间存储变量地址

    【2】从底层汇编指令角度来看,引用是类似于指针方式实现的

    auto用法

    可以自动推导变量的类型

    1. int a=1;
    2. auto b=1+1.11;//可以根据右边表达式,自动推导出b是double类型的
    3. cout<<typeid(b).name()<//输出变量的数据类型

    以后学到迭代器之后,代码会很长,写起来比较麻烦,所以用aoto较为简便

    注意:

    1、auto不能做函数参数

    1. void Test(auto a)//这种写法是错误的
    2. {
    3. ,,,
    4. }

    2、不能直接声明数组

    1. void test()
    2. {
    3. auto b[]={1,2,3,4};//这也是错误的
    4. }

    范围for(语法糖)

    1. //自动推导类型,依次取出数组中元素,赋值给e,自动迭代和判断结束
    2. int arr[10]={1,2,3,4,5,6,7,8,9,0};
    3. for(auto e:arr)
    4. {
    5. cout<" ";
    6. }

  • 相关阅读:
    深圳汇报片制作需要优先了解哪些信息
    快捷键查询大全(包括VSCode、PyCharm 强烈建议收藏)
    MySQL大表数据导入到MongoDB
    谷歌AudioLM :通过歌曲片段生成后续的音乐
    算法27:最长公共子序列——样本模型(4)
    银发经济硬战:福寿康稳步拓荒,小柏家护轻装上阵
    Linux cpu 亲缘性 绑核
    明星录制祝福视频:传递温情与关怀的独特方式
    ES9,ES10
    栈的压入、弹出序列
  • 原文地址:https://blog.csdn.net/awww224112/article/details/132776470