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

    合类型是指基于其他类型定义的类型。C++语言有几种符合类型,引用和指针

    1、引用。(左值引用)

    引用为对象起了另外一个名字,引用类型另外一种类型。通过声明符写成&d的形式来定义引用类型。其中d是生命的变量名。

    int a=1024;

    int &val=a;//val指向a(是a的另一个名字)

    int &cal;//报错,引用必须被初始化

      一般在初始化变量时,初始值会被拷贝到新建的对象中。然而定义引用时,程序把引用和他的初始值绑定在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。

    引用即别名:引用并非对象,相反的,他只是为一个已经存在的对象所起的另外一个名字。

      定义了一个引用之后,对其进行的所有操作都是在与之绑定的对象上进行的。为引用赋值,实际上是把值赋给了与引用绑定的对象。获取引用的值,实际上是获取了与引用绑定的对象的值。

    2、指针:

    是指向另外一种类型的复合类型。与引用类似,指针也实现了对其他对象的间接访问。然而指针与引用相比又有很大的不同点。其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它还可以先后指向几个不同的对象。其二,指针无需在定义时候就赋值,和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。

    int * p;p是指向int类型对象的指针。

    获取对象的地址:指针存放某个对象的地址,要想获取该地址,需要使用取地址符号(&)int val=24;int * p=&val;//p值存放变量val的内存地址,或者说p是指向变量val的指针。

    因为在声明语句中指针类型实际上被用于指定他所指向对象的类型,所以二者必须匹配。

    指针值:(即地址)因属于4种状态之一:

    1、指向一个对象

    2、指向紧邻对象所占空间的下一个位置。

    3、空指针,没有指向任何对象。

    4、无效指针

    利用指针访问对象:如果指针指向了一个对象,则允许使用解引用符(*)来访问对象:int val=32;int * p=& val;cout<<*p;

    解引用符只是应用于那些确实指向了某个对象的有效指针。

    空指针:不知向任何对象,在试图使用一个指针之前代码首先检查他是否为空。

    赋值与指针:指针和引用都能提供其他引用对象的简介访问,然而具体实现细节上二者有很大的不同,其中最重要的一点就是引用本身并非一个对象。一旦使用了引用,就无法令其在绑定到另外的对象,之后每次使用这个引用都是访问它最初绑定的那个对象。

    指针和他存放的地址之间就没有这种限制。给指针赋值就是令他存放一个新的地址,从而指向一个对象:

    int i=43;

    int * p1=0;//p1被初始化没有指向对象

    int * p2=& i;//p2被初始化,存有i的地址

    int * p3;//这是个野的指针

    p3=p2;//p3和p2指向同一个对象

    p2=0;//p2不指向任何对象

    注意:等号=永远改变的是等号左边的对象。

    void *指针:

    void* 是一种特殊的指针类型,可用于存放任意对象的地址。一个void*指针存放值一个地址,这一点和其他指针类似。不同的是,我们对该地址到底是个什么类型的的对象并不了解

    指针和引用的主要区别:

    指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法。

    1.指针和引用的定义和性质区别:

    (1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。如:

    int a=1;int *p=&a;

    int a=1;int &b=a;

    上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。

    而下面2句定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。

    (2)可以有const指针,但是没有const引用;

    (3)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)

    (4)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;

    (5)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。

    (6)"sizeof引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小;

    (7)指针和引用的自增(++)运算意义不一样;

    2.指针和引用作为函数参数进行传递时的区别。

    (1)指针作为参数进行传递:

    复制代码

    #include<iostream>using namespace std;void swap(int *a,int *b)
    {
      int temp=*a;
      *a=*b;
      *b=temp;
    }int main(void)
    {
      int a=1,b=2;
      swap(&a,&b);
      cout<<a<<" "<<b<<endl;
      system("pause");
      return 0;
    }

    复制代码

    结果为2 1;

    用指针传递参数,可以实现对实参进行改变的目的,是因为传递过来的是实参的地址,因此使用*a实际上是取存储实参的内存单元里的数据,即是对实参进行改变,因此可以达到目的。

    再看一个程序;

    复制代码

    #include<iostream>using namespace std;void test(int *p)
    {
      int a=1;
      p=&a;
      cout<<p<<" "<<*p<<endl;
    }int main(void)
    {
        int *p=NULL;
        test(p);
        if(p==NULL)
        cout<<"指针p为NULL"<<endl;
        system("pause");
        return 0;
    }

    复制代码

    运行结果为:

    0x22ff44 1

    指针p为NULL

    大家可能会感到奇怪,怎么回事,不是传递的是地址么,怎么p回事NULL?事实上,在main函数中声明了一个指针p,并赋值为NULL,当调用test函数时,事实上传递的也是地址,只不过传递的是指地址。也就是说将指针作为参数进行传递时,事实上也是值传递,只不过传递的是地址。当把指针作为参数进行传递时,也是将实参的一个拷贝传递给形参,即上面程序main函数中的p何test函数中使用的p不是同一个变量,存储2个变量p的单元也不相同(只是2个p指向同一个存储单元),那么在test函数中对p进行修改,并不会影响到main函数中的p的值。

    如果要想达到也同时修改的目的的话,就得使用引用了。

    2.将引用作为函数的参数进行传递。

    在讲引用作为函数参数进行传递时,实质上传递的是实参本身,即传递进来的不是实参的一个拷贝,因此对形参的修改其实是对实参的修改,所以在用引用进行参数传递时,不仅节约时间,而且可以节约空间。

    看下面这个程序:

    复制代码

    #include<iostream>using namespace std;void test(int &a)
    {
      cout<<&a<<" "<<a<<endl;
    }int main(void)
    {
        int a=1;
        cout<<&a<<" "<<a<<endl;
        test(a);
        system("pause");
        return 0;
    }

    复制代码

    输出结果为: 0x22ff44 1

              0x22ff44 1

    再看下这个程序:

    这足以说明用引用进行参数传递时,事实上传递的是实参本身,而不是拷贝。

    所以在上述要达到同时修改指针的目的的话,就得使用引用了。

    复制代码

    #include<iostream>using namespace std;void test(int *&p)
    {
      int a=1;
      p=&a;
      cout<<p<<" "<<*p<<endl;
    }int main(void)
    {
        int *p=NULL;
        test(p);
        if(p!=NULL)
        cout<<"指针p不为NULL"<<endl;
        system("pause");
        return 0;
    }

    复制代码

    输出结果为:0x22ff44 1

             指针p不为NULL

  • 相关阅读:
    2019.9.18 csp-s模拟测试46 反思总结
    2019.9.17 csp-s模拟测试45 反思总结
    矩阵求导(包含极大似然估计)
    sir
    Square into Squares. Protect trees!(平方数分解平方和)
    最小二乘法
    2.5&2.6 numpy&pandas 笔记
    2.4 python学习笔记
    2.3 python学习笔记
    2.1&2.2python学习笔记
  • 原文地址:https://www.cnblogs.com/yjds/p/8597179.html
Copyright © 2011-2022 走看看