zoukankan      html  css  js  c++  java
  • c++中的复合类型

      复合类型是指基于其他类型而定义的类型。 而这里介绍的是引用和指针。并且指针和引用都提供了对其他对象的间接访问。

      

    引用

      引用还是很好理解的,就是为对象起了另外一个名字,引用类型引用另外一种类型。 通常将声明符协程 &d 的形式来定义引用类型,其中d是声明的变量名。   

      注意:引用不是对象。 

      一般,在初始化变量时,如int a = 3; int b = a; 这时,这里b的初始化就会将a的值拷贝到新建的对象中。即int b = 3这里新建了一个对象来存储,对a和b的操作是独立的。 而定义引用时,程序会把引用和他的初始值绑定在一起,而不是将初始值拷贝给引用。如下所示:

    #include <iostream>
    using namespace std;
    int main()
    {
        cout << "beginning!" << endl;
        int a = 2;
        int &b = a;
        cout << "b的值为:" << b << endl; // 2
        b = 5;
        cout << "a的值为:" << a << "	 b的值为:" << b << endl; // a 和 b都是5
        return 0;
    }

      如上,我们可以看到:b就是a的引用,这里b的值也是2,所以引用就是给a了一个别名b,并且并没有给b一个新的对象,而是将b和a绑定在了一起,我们修改b的值,发现a和b的值同时修改成了5,这就是引用。 

      那么引用的目的是怎样的呢? 一般来说,引用比指针更容易操作、也更不容易出错。可以代替指针。

      需要注意的:

    • 引用必须赋初值。
    • 引用和之前的类型要严格匹配。
    • 如上的int &b 是指引用类型b是指向int类型的引用。 

    指针

      指针是指向另外一种类型的复合类型。

      指针如果要指向某个对象,是存放着某个对象的地址。 如下:

        int a = 10;
        int *p = &a;
        cout << &a << endl;

      其中&a就是获取a的地址。  int *p是指p是一个指向int类型对象的指针。 

      以上,我们已经定义了指针,那么如何利用指针访问它所指的对象呢? 使用 * 解引用符即可。 

        int a = 10;
        int *p = &a;
        cout << *p << endl; // 10

      如上所示: 我们可以得到 *p 的值为10。 

      

      注意: 某些符号具有多重含义!这里讲解 * 和 &。 

      int i = 42;

      int &r = i;  // &紧随类型名出现,这里的&为引用。 

      int *p; // *紧随类型名出现,这里的 * 为定义指针类型的p。  

      p = &i; // 这里的&出现在表达式中,是一个取地址符。

      *p = i; // 这里的 * 出现在表达式中,是一个解引用符。 

      int &r2 = *p; // 这里的 * 出现在表达式中,是一个解引用符。 

      

      

    空指针

      即Null pointer,它是不指向任何对象的,一般我们建议:初始化所有的指针,并且在可能的情况下,尽量等定义了对象之后在定义指向他的指针,如果不清楚它指向何处,就初始化为空指针。

      定义空指针一般有三种方法,如下所示:

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    void IsNull(int *p);
    int main()
    {
        cout << "beginning!" << endl;
        int *p = 0;
        IsNull(p);
        int *p1 = nullptr;
        IsNull(p1);
        int *p2 = NULL;
        IsNull(p2);
        int a = 5, *p3 = &a;
        IsNull(p3);
        return 0;
    }
    void IsNull(int *p)
    {
        if (p == nullptr)
        {
            cout << "空指针" << endl;
        }
        else
        {
            cout << "非空指针" << endl;
        }
    }

      三种方法为赋值为0、赋值为NULL、赋值为 nullptr,最后一种方法是c++11所新定义的,也是我们推荐的,在判断一个指针是否为空指针时,我们只需要判断其是否与nullptr相等即可。 注意:NULL的值就是0,是在 cstdlib 库中定义的。

      注意:如果指针没有初始化为空指针或者指向明确的对象,那么很有可能会导致整个程序的崩溃,并且难以入手解决问题。

        int i = 42;
        int *pi = 0; // 定义pi为空指针
        int *pi2 = &i; // pi2指向i
        cout << *pi2 << endl;
        int *pi3;
    
        pi3 = pi2; // 注意:这里并不是Pi3指向pi2,而是pi3指向了和pi2相同的对象,即这时pi3同样指向i。 
        pi2 = 0;
        cout << *pi3; // 42
        cout << *pi2; // 报错

    另外,如果指针指向为空,则if判断时的结果为false,且指针之间可以使用 == 来判断是否相等,比如指向同一个对象、都为空等等。

    注意: void*指针可以存放任何类型的对象,不受限制,但利用也比较有限。 

      

    总结

      指针和引用都提供了访问对象的其他方法,但为什么c++中同时有指针和引用呢? 如下:

    可以看到,在第一个例子中,显然使用引用更加舒服一些。 另外,我们怎么理解这种参数的使用方式呢,实际,f1要求的两个指针,比如f1在调用时是f1(p1, p2),即const complex * x = p1。 因为p1是指针,可以直接赋值。 

    指向指针的指针  

      

            int i = 42;
    	int *p1 = &i;
    	int *p2 = nullptr;
    	p2 = p1;
    	cout << *p2; //42

    如上所示,p2 = p1的意思是p2指针指向p1指针所指向的对象,而不是p2指向p1,那么如何定义p2指向p1,即指向指针的指针呢?

        int i = 42;
        int *p1 = &i;
        int **p2 = &p1;
        cout << **p2; //42

    如上所示: p2就是一个指向指针的指针。 

    指向指针的引用

      指针是对象,所以可以有指向指针的引用,如下:

        int i = 42;
        int *p1 = &i;
        int  *&r = p1; // 这里的r就是指向指针的引用
        *r = 365;
        cout << *r;  //365

      如上所示:p1是指向int型变量i的指针,而 r 是指向指针型变量的引用,即我们对r的操作就是对p1的操作,因此,我们可以得到最后的结果为365。 

    参考链接:http://www.stroustrup.com/bs_faq2.html#pointers-and-references

  • 相关阅读:
    C#基础知识汇总(不断更新中)
    比较两个DataTable是否相等
    C#利用SerialPort控件进行串口编程小记
    C# ListBox 自动滚动到底部 方法:
    IIS配置文件的XML格式不正确 applicationHost.config崩溃 恢复解决办法
    net4log 添加自定义变量
    net4log 日志管理
    C#实现加简单的Http请求
    H5,Css小姐又作画了
    H5 ,Css实现了你的logo
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/8600258.html
Copyright © 2011-2022 走看看