• 引用、数组引用与指针引用、内联函数inline、四种类型转换运算符


    一、引用

    (1)、引用是给一个变量起别名
    定义引用的一般格式:类型  &引用名 = 变量名;
    例如:int a=1;  int  &b=a;// b是a的别名,因此a和b是同一个单元 注意:定义引用时一定要初始化,指明该引用是谁的别名 在实际应用中,引用一般用作参数传递与返回值

    引用不是变量,引用仅仅只是变量的别名,引用没有自己独立的空间,引用要与它所引用的变量共享空间,对引用所做的改变实际上是对它所引用的变量的改变,引用在定义的时候要进行初始化,引用一经初始化,不能重新指向其他变量。


    (2)const 引用

    const引用是指向const对象的引用

    const int ival = 1024;
    const int& refVal = ival; //ok:both reference and object are const int &ref2 = ival; //error:nonconst reference to a const object


    (3)、按引用传递

    引用传递方式是在函数定义时在形参前面加上引用运算符"&"
    例如:swap(int &a,int &b);
    按值传递方式容易理解,但形参值的改变不能对实参产生影响
    地址传递方式通过形参的改变使相应的实参改变,但程序容易产生错误且难以阅读
    引用作为参数对形参的任何操作都能改变相应的实参的数据,又使函数调用显得方便、自然

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #include <iostream>
    using namespace std;
    void swap(int &x, int &y);
    int main(void)
    {
        int a, b;
        a = 10;
        b = 20;
        swap(a, b);
        cout << "a=" << a << "b=" << b << endl;
        return 0;
    }
    void swap(int &x, int &y)
    {
        int temp;
        temp = x;
        x = y;
        y = temp;
    }

    注意:引用作参数时,函数的实参与形参在内存中共用存储单元,因此形参的变化会使实参同时变化。

    (4)、引用作为返回值

    引用的另一个作用是用于返回引用的函数
    函数返回引用的一个主要目的是可以将函数放在赋值运算符的左边。
    注意:不能返回对局部变量的引用,具体可以参见我的这篇文章,文章里面还比较了引用与指针的关系。

    (5)、引用与指针区别

    引用访问一个变量是直接访问,而指针是间接访问。
    引用是一个变量的别名,本身不单独分配自己的内存空间,而指针有自己的内存空间。
    引用一经初始化不能再引用其它变量,而指针可以。
    c++建议尽可能使用引用,不得已时使用指针。


    二、数组引用与指针引用

    请注意:sizeof 返回的是ssize_t (32位下4字节,64位为8字节)

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    /*************************************************************************
        > File Name: test.cpp
        > Author: Simba
        > Mail: dameng34@163.com 
        > Created Time: Wed 21 May 2014 06:50:11 PM PDT
     ************************************************************************/

    #include<iostream>
    using namespace std;

    void func1(char s[10]) // char *s 
    {
        cout<<"func1"<<endl;
        cout<<sizeof(s)<<endl;
        cout<<s[1]<<endl;
        s[1] = 'B';
        cout<<s[1]<<endl;   
    }

    void func2(char (&ss)[100])  // 数组引用
    {
        cout<<"func2"<<endl;
        cout<<sizeof(ss)<<endl;
        cout<<ss[1]<<endl;
        char * f2 = ss;
        f2[1] = 'D';
        cout<<f2[1]<<endl;
    }


    void func3(char * const &  sss)// 指针引用
    {
        cout<<"func3"<<endl;
        cout<<sizeof(sss)<<endl;
        cout<<sss[1]<<endl;
        char * f3 = sss;
        f3[1] = 'F';
        cout<<f3[1]<<endl;
    }


    int main(void)
    {

        char s[10] = {'a', 'b'};
        char ss[100] = {'c', 'd'};
        char sss[1000] = {'e', 'f'};

        cout<<"main fun"<<endl;
        cout<<sizeof(s)<<endl;

        func1(s);
        func2(ss);
    //  func2(sss);  error
        func3(sss);

        return 0;
    }

    输出为:

    simba@ubuntu:~/Documents/code/cpp$ g++ test.cpp -o test
    simba@ubuntu:~/Documents/code/cpp$ ./test 
    main fun
    10
    func1
    4
    b
    B
    func2
    100
    d
    D
    func3
    4
    f
    F

    如果数组为const char s[n]; 那么三个func的参数前面都得加const,当然此时就不能够在函数里面修改数组元素了。


    三、内联函数

    (1)、内联函数

    当程序执行函数调用时,系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等等,这些工作需要系统时间和空间的开销。有些情况下,函数本身功能简单,代码很短,但使用频率却很高,程序频繁调用该函数所花费的时间却很多,从而使得程序执行效率降低。

    为了提高效率,一个解决办法就是不使用函数,直接将函数的代码嵌入到程序中,可以使用带参数的宏定义实现,但是这种方法也有缺点,程序可读性往往没有使用函数的好,如果缺少了一些括号还可能出现歧义。
    为了协调好效率和可读性之间的矛盾,C++提供了另一种方法,即定义内联函数,方法是在定义函数时用修饰词inline。inline关键字告诉编译器,这个函数的调用要尽可能快,可以当普通的函数调用实现,也可以用宏展开的办法实现。在C99也引入了inline 关键字。

    (2)、内联函数和带参数的宏的区别

    inline int max(int a, int b)
    {
    return a > b ? a : b;
    }
    #define MAX(a, b)  ((a) > (b) ? (a) : (b))

    内联函数调用时,要求实参和形参的类型一致,另外内联函数会先对实参表达式进行求值,然后传递给形参;如果实参表达式有Side Effect,那么这些SideEffect只发生一次。例如MAX(++a, ++b),如果MAX是个真正的函数,a和b只增加一次。而宏调用时只用实参简单地替换形参;如果MAX是上面那样的宏定义,则要展开成k = ((++a)>(++b)?(++a):(++b)),a和b 增加的次数就难说了。
    内联函数是在编译的时候、在调用的地方将代码展开的,而参数宏则是在预处理时进行替换的,故生成的目标文件都比较大。

    在C++中建议采用inline函数来替换带参数的宏。


    四、四种类型转换

    参考我的这篇文章


    参考:

    C++ primer 第四版
    Effective C++ 3rd
    C++编程规范

  • 相关阅读:
    百度开源其NLP主题模型工具包,文本分类等场景可直接使用L——LDA进行主题选择本质就是降维,然后用于推荐或者分类
    谷歌开源可视化工具Facets,将用于人+AI协作项目研究——无非就是一个用于特征工程探索的绘图工具集,pandas可以做的
    机器学习案例 特征组合——高帅富 冷启动——从微博等其他渠道搜集数据进行机器学习 用户年龄——线性分段处理
    pyspark MLlib踩坑之model predict+rdd map zip,zip使用尤其注意啊啊啊!
    [038] 微信公众帐号开发教程第14篇-自定义菜单的创建及菜单事件响应
    [037] 微信公众帐号开发教程第13篇-图文消息全攻略
    [036] 微信公众帐号开发教程第12篇-符号表情的发送(下)(转)
    [035] 微信公众帐号开发教程第11篇-符号表情的发送(上)(转)
    [034] 微信公众帐号开发教程第10篇-解析接口中的消息创建时间CreateTime(转)
    [033] 微信公众帐号开发教程第9篇-QQ表情的发送与接收(转)
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8470994.html
Copyright © 2020-2023  润新知