zoukankan      html  css  js  c++  java
  • 2、C++ 的升级


    1、内联函数

        define 可以定义宏代码片段,但是,C++ 推荐使用内联函数替代宏代码片段。

    inline int f(int a, int b)
    {
    }

        只需要在 函数定义(实现)的前面添加 inline 关键字。内联函数的出现是为了替代宏代码的片段

    定义:

        内联函数,其实就会将内联函数的内部直接插入到被调用的地方,所以就没有了,调用子函数的出入栈的操作的开销,一定程度上节约了开销。

    优点:

        省去调用的过程,不用出入栈的操作,减少开销,加快运行的速度。

    缺点:

        使用一次内联函数,就插入函数,这样程序的体积会变得很大

    注意其实就是拿空间开销和时间开销做替换而已,内联函数牺牲了空间开销节约了时间开销。

    内联函数和宏代码段的区别

    内联函数的本质上还是一个函数,具有普通之后函数的特征,比如做参数的检查,返回类型等等,内联函数经过编译器处理,直接将代码插入调用的地方。

        宏代码端,是由预处理执行,只是做简单的文本替换,

    内联函数的限制

        内联函数的优点是,少了出入栈的操作,节省了开销,但是,当内联函数的运行的开销大于出入栈的开销的时候,这个时候,内联函数就是鸡肋了。所以内联函数还是存在限制的:

        (1)不能存在任何形式的循环语句

        (2)不能存在判断语句

        (3)运行开销大于出入栈的开销,一般的代码行数不超过五行

        (4)不能对函数进行取址的操作

    内联函数实现的机制

        编译器发现有内联函数的时候,就将这                

    b6c1baec-5e38-4593-9071-c985ed197333

        当发现使用内联函数的时候,首先进行类型检查,将符号表的里面的值,插入到调用的位置。

    2、函数默认的参数

        C++ 可以在函数声明的时候为参数提供一个默认值,当函数使用的时候没有指定这个参数的值,那么编译器会自动使用默认的值;

    int  f(int a = 1, int b = 1);  // 函数的声明,声明的时候提供默认值
     int  f(int a, int b) // 函数的定义,
    {// 虽然没有对 ab 进行赋值,所以使用的是函数声明时候,提供的默认值
        printf("a = %d, b = %d 
    ",a, b);
    }

    函数声明提供函数默认参数的规则

    int  f(int a, int b = 0, int c = 1);
     int  f(int a, int b,int c)
    {
        printf("a = %d, b = %d 
    ",a, b);
        return 0;
    }

        规则是,一旦一个函数从某一个开始提供默认值的时候,那么之后所有的默认值都必须进行提供,不然报错,也就是说, 假如例子,从第一个 a 就提供了默认的参数值,那么后面的所有的参数都必须提供默认的参数值。

        调用的时候,f(参数),当参数为一个数值的时候,那么这个数值就会传入给变量 a,当传入两个的时候,就将数值传入给变量a、b;

    3、函数的占位参数

        占位参数,就是只有函数的参数的类型的声明,而没有参数的名,比如:

    int  f(int a, int b,int)

    使用的时候,我们也是必须传入三个参数,但是最后一个参数,是没有被使用到的。

    函数占位参数的意义:

        (1)为以后程序的扩展留下一个线索:告诉后面的程序猿,这个地方可以做扩展,

        (2)兼容C语言程序中,出现的不规范的写法,

    4、函数的重载(overload)

        使用相同的函数名,完成不同的功能,这个就是重载函数

    int  func(int a)
    {
        return x;
    }
     int  func(int a,int b)
     {
         return a + b;
     }
    
     int  func(char *s)
     {
         return strlen(s);
     }

        可见,函数名都是完全相同的,但是这个函数,完成了不同的功能。所以他们肯定是有所区分的,区分的手段 : 参数的个数,参数的类型,参数的顺序


    问题: 当重载函数遇见函数提供默认的参数

    int func(int a,int b,int c = 0)
     {
         return a + b + c;
     }
     int func(int a, int b)
     {
         return a + b;
     }
    int main()
    {
        func(1, 2);  // 指定哪一个 函数呢
    }

        正确的是,编译器会报错,编译器发现了二义性,两个func 都是可以被执行的,编译器也是不了解,

    注意:

        函数的返回值,不能作为函数重载的依据,也就是说,函数的重载只能在参数的个数,参数的类型,参数的顺序上做区分。


    5、C语言和C++的相互调用


    C++ 调用C编写的函数:

        C++的编译器虽然是可以兼容C语言的编译方式,但是C++的编译器会优先使用C++的编译方式,但是,如果想C++ 调用 C语言的函数的话,必须加入 extern 关键字,告诉编译器,这个函数使用C语言的方式进行编译。

    extern "c" {内容,比如函数或者头文件}

    告诉编译器,内容的部分,可以是声明的函数或者变量使用的是C编译器编译的方式

    C调用C++编写的函数:


    统一的解决的方案:

        __cplusplus :

        使得C代码可以通过c编译器进行编译,也可以在C++的编译器中,以C的方式进行编译,,

    #ifdef __cplusplus
    extern "c"
    {
    #endif
    // 函数的声明或者函数的定义
    #ifdef __cplusplus
    }
    #endif

     

     

    C++编译器不能以C编译的方式去编译函数重载的问题

        函数的重载,是在C++才有的,所以函数重载的问题,不能以C编译的方式去编译,所以,

    #ifdef __cplusplus
    extern "C"
    {
    #endif // __cplusplus
        int func(int a, int b, int c = 0)
        {
            return a + b + c;
        }
        int func(int a, int b)
        {
            return a + b;
        }
    #ifdef __cplusplus
    }
    #endif

        以C编译的方式函数重载的话,就肯定会报错,

  • 相关阅读:
    jquery.validate ajax提交
    linux权限不够,sh不能用
    几个简单的基类
    类型转换辅助工具类TypeCaseHelper
    linux下修改tomcat内存大小
    Hibernate,JPA注解@OneToMany_Map
    Hibernate,JPA注解@OneToMany_Set
    Hibernate,JPA注解@PrimaryKeyJoinColumn
    Hibernate,JPA注解@OneToOne_JoinColumn
    Hibernate,JPA注解@SecondaryTables
  • 原文地址:https://www.cnblogs.com/qxj511/p/5212666.html
Copyright © 2011-2022 走看看