zoukankan      html  css  js  c++  java
  • C和C++的一些区别

    1.带有默认值的函数  

       在C语言里面没有带默认值的函数,C++支持带默认值的函数。 

      在给形参默认值的时候,要按照从右向左的顺序。

      可以在定义处给,也可以在声明处给。但是同一个变量的默认值只能给一次,给多次相同的默认值也不行。

      调用的时候可以只传入没有默认值的实参,有默认值的可以不用传递。如果传了实参,函数调用时,在汇编上先压实参,按从右向左的顺序;如果没有传实参,编译器会将形参给的默认值直接压到栈上。

     

    int sum(int a,int b=20)
    {
        return a+b;
    }
    int main()
    {
        int a = 10;
        int b = 25;
        sum(a,b);
        /*
        ebp esp
        mov eax ,dword ptr[ebp-8] //从内存中将b的值取出来放入寄存器中
        push eax                  //把值压到栈上
        mov ecx, dword ptr[ebp-4]
        push ecx
        call sum
        add esp,8 esp+=8
        */
        sum(a);
        sum(a,30);               //和sum(a)在汇编上一样,没有区别
        /*
        push 14h
        mov ecx, dword ptr[ebp-4]
        push ecx
        call sum
        */
    
        return 0;
    }

    所以,使用带有默认值的函数会提高效率,相当于节省了一个mov指令的周期。

    2.inline函数

     (1)

      内联函数:在函数的调用点,把函数的代码全部展开(编译过程)

      宏:在预编译阶段处理

      内联函数相当于一种更安全的宏,因为在预处理阶段不进行检查,只是进行替换,而编译阶段会进行类型检查,所以更安全。有内联函数后,尽量不用宏,因为用宏写的代码不能调试。

     (2)

      

      内联函数在调用点直接展开,不产生符号,只在本文件可见,在另一个文件不能通过声明在链接阶段定位到另一个文件中的内联函数,所以内联函数一般写在头文件中

      这样会出错,sum()重复定义,所以可以写成内联函数,就只在当前文件可见。

     (3)

      inline 只在release版本起作用。在debug版本里面,inline函数的调用也需要栈帧的开辟和回退(主要是为了方便调试)。

      而且inline只是对编译器的一个建议,最终是由编译器来决定是否处理成内联。

      递归的函数不能处理成内联。

     (4)

    • 内联函数和普通函数的区别?

      1.内联函数没有标准的函数栈帧的开辟和回退,而普通函数有。

      所以函数过于短时,一般处理成内联函数,当调用函数的开销(栈帧开辟和回退)大于函数执行的开销时,用内联函数就省去了调用函数的开销。

      2.内联函数不产生符号。

    • 内联函数和static函数的区别?

      1.都是文件可见(作用域)。

      2.栈帧的开辟和回退不一样。调用static函数时有正常的栈帧开辟和回退,和普通函数一样。

      3.static函数产生符号。

    • static函数和普通函数的区别?

      static函数产生的符号都是local的,链接器不处理。

      普通函数产生global符号。

     3.函数的重载

    在C语言中,函数产生符号是由函数名决定的;

    在C++中,函数产生符号,是由 函数名称+形参类型+形参个数 决定的。

    (1)函数名相同,参数列表不同的一组函数称作一组重载的函数。

      (不能仅通过返回值的不同来进行重载,因为函数符号的产生和返回值没关系。)

    (2)重载必须处于同一个作用域之内。

      在C和C++里,全局和局部作用域可以定义同名的函数,但局部使用时,优先使用局部的。

      C和C++允许不同作用域产生相同名的符号。

    (3)对实参的值是否有影响。

      const/volatile 所修饰的指针或者引用可以作为函数重载的前提条件。

    4.const

    用 const 修饰的量都变成一个不能被修改的量

     

    (1)

    • C语言里面的 const 不是必须初始化的,但如果不初始化,我们之后就没有机会再给它一个合法的值了。所以虽然不是必须初始化,但我们一般都会给一个初始化的值。
    • C中 const 修饰的量叫常变量(不能作为数组下标),不叫常量。
    • const 修饰的常变量和普通变量唯一的区别就是:常变量定义以后,不能作为左值存在。
    • 常变量和普通变量在C语言中的编译方式一模一样。

    (2)

    • C++中的 const 必须初始化。
    • C++中 const 修饰的量是一个常量(可以当作数组下标用)。
    • 在C++中编译规则:所有使用常量名字的地方全部替换成常量的初始值,所以C++规定常量必须给初始化。

      

        

      a的打印结果是10,是因为在编译的时候,所有是常量名字的地方都被替换成了初始值,

      *p打印结果是30,是因为这只是引用了常量的地址,不是在引用常量的值,只有在引用常量值的地方才进行替换。

      ** C++的常量在引用一个编译阶段不明确的值的时候会退化成和C语言一样的常变量。

  • 相关阅读:
    Oracle sql的基本优化写法和思路。
    Linux的简单介绍和开发基本运维时候用到的命令
    Nginx的使用(反向代理,负载均衡)
    Mybatis传值为空需要配置JdbcType来解决吗?(XML文件不需要配置JdbcType)
    Mybatis Blob和String互转,实现文件上传等。
    Ckeditor上传图片返回的JS直接显示出来,未执行!!!
    学习中的错误——ubuntu 14.04 LTS 启动eclipse报错
    2016计算机大会后记——机器学习:发展与未来
    2016计算机大会后记——大数据时代的模式识别
    近期编程问题——epoll failed:bad file descriptor
  • 原文地址:https://www.cnblogs.com/lulu1997/p/8806755.html
Copyright © 2011-2022 走看看