zoukankan      html  css  js  c++  java
  • c/c++ 复习基础要点01-const指针、指针函数 函数指针、new/delete与malloc/free区别与联系

    1.      引用本身是有指针实现的:引用为只读指针

    例子:

         int d=123;

         int& e=d;    //引用

         int * const e=d; //只读指针,e指向d,不可修改e指向别的变量

    2.      const修饰指针问题

    2.1.指向const对象的指针:

          const double *cptr;

             const 所限定的是指针所指的对象,而非限定指针为const

          例子:

               const double ip=3.14;   //ip为const型

               const double *cptr=&ip; 

               //cptr不是const型 ,ip不能赋值为一个非const的指针

           注意:不能用void*指针保存const对象的地址,而必须使用const void*类型的指针保存const对象的地址。

                 可以把非const对象的地址赋值给指向const对象的指针(const void *),则不可修改用指向const对象的指针来修改非const变量。

    实例:

    #include<iostream>

    int  main()

    {

          const int a=12;

          int * ptr=&a;   //error

          const int * cptr=&a;  //ok

          int b=20;

          ptr=&b;

          cptr=&b;

          cout<<b<<endl;

          cptr=15;     //error

          ptr=15;      //ok

          cout<<b<<endl;

          return 0; 

    }

    2.2.const指针(只读指针)

    int a=0;

    int *constptr=&a;

    const指针存放的地址不能修改,初始化后,指针a不能指向其他的对象。

    指针a指向一个普通的非constint型对象a,则可使用指针b修改该对象的值。

    2.3.指向const对象的const指针

    const doubleip=3.14;

    const double *const pi=&ip;

         指针所指的对象不可改变,对象的值也不可改变

    3.      空指针

    void * 指针

    void*类型可以保存任意类型对象的地址

    void*支持的操作:

         与另一个指针进行比较;

         向函数传递void*指针或者从函数返回void*指针;

         给另一个void*指针赋值

     不能使用void*指针操作它所指向的对象。

    4.      指针函数、函数指针

    4.1.指针函数(为函数):

           如果一个函数的返回值是指针类型,则称为指针函数。

           数据类型  *函数名(形参类表)

            {

                  函数体

            }

           用指针作为函数的返回值的好处是:可以从被调函数向朱调函数返回大量数据。

           不要把指针函数内部的局部变量赋值为指针返回:

           例如:

    #include<iostream>

    usingspacename  std;

    int *fun();

    void  main()

    {

       int *pfr;

       pfr=fun();

      cout<<"*pfr="<<*pfr<<endl;

    }

    int  *fun()

    {

       int va;

       int *ptr=&va;

       *ptr=5;

      cout<<"ptr="<<*ptr<<endl;

       return ptr;         //error   因为函数内的局部变量在函数结束时就注销了,指针ptr将变成悬垂指针。

    }

    应该:

    #include<iostream>

    using  spacename std;

    int *fun();

    void main()

    {

      int *pfr;

      pfr=fun();

     cout<<"*pfr="<<*pfr<<endl;

    }

    int  *fun()

    {

      int *pfr=new int;

      *pfr=5;

      cout<<"*pfr="<<*pfr<<endl;

      return ptr;

    }

    4.2.函数指针:

    指针不仅可以指向变量,还可以指向函数,指向函数的指针称为函数指针。

    数据结构  (*指针名)(形参类表);

    数据类型代表指针所指向函数的返回类,形参列表是指针所指向函数的形参列表。

          列如:

             int (*fptr)(int,int);

           定义函数指针后,就可以为它赋值,使它指向某个特定的函数:

           函数指针名=函数名;

    例子:

    #include<iostream>

    using spacename std;

    float areaofRectangle(float width,floatheight);

    float areaofTriangle(float heml,floatheight);

    void main()

    {

     float (*fptr)(float,float);

     float area,worh,height;

     cout<<"请输入矩形的高和宽:";

     cin>>worh>>height;

     fptr=areaofRectangle;

     area=fptr(worh,height);

     cout<<"举行面积为:"<<area<<endl;

     cout<<"请输入三角形的底和高:";

     cin>>worh>>height;

     fptr=areaofTriangle;

     area=fptr(wroh,height);

     cout<<"三角形面积为:"<<area<<endl;

    }

    float areaofRectangle(float width,floatheight)

    {

     return width*height;

    }

    float areaofTriangle(float heml,float height)

    {

     return (heml*height)/2;

    }

    5.      new delete 与 malloc free 的区别于联系

    相同点:都是用于申请动态内存和释放内存

    不同点:

    (1)      操作对象有所不同。

    malloc与free是c语言的标准库函数,new/delete是c++的运算符。对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数任务强加malloc/free。

    (2)      用法上也有所不同。

    函数malloc的原型如下:

    void * malloc(size_t  size);

    用malloc申请一块长度为length的整数类型的内存,如下:

    int * p=(int)malloc(sizeof(int)*length);

    我们应该把注意力集中在两个要素上:

    1.      malloc返回值的类型是void*,所以在调用malloc时要显示地进行类型的转换,将void* 转换成所需要的指针类型。

    2.      malloc函数本身并不识别要申请的内存是什么类型,它只关心内存的总的字节数。

             函数free的原型如下:

              void free(void * memblock);

               为什么free函数不像malloc函数那样复杂呢?这是因为指针p的类型以及它所指的内存的容量事先都是知道,语句free(p)能正确地释放内存。如果p是NULL指针,那么free对p无论做多少次操作都不会出问题。如果p不是NULL指针,那么free对p连续操作两次就会导致程序运行错误。

               new/delete的使用要点:

               运算符new使用起来要比函数malloc简单多了,例如:

               int *p1=(int)malloc(sizeof(int)*length);

               int *p2=new int[length];

               这是因为new内置了sizeof、类型转换盒类型安全检查功能。对于非内部数据类型的对象而言,new在创建动态对象的同时完成了初始化工作。如果对象有多个构造函数,那么new的语句也可以有多种形式。

              

        如果用new创建对象数组,那么只能使用对象的无参构造函数。

        Obj *objects = newObj[100];   //创建100个动态对象

        不能写成

         Obj * objects = newObj[100](1);  //创建100个动态对象的同时赋值初值1

        在用delete释放对象数组时,留言不要丢了符号[]。

        delete []objects;   //正确的用法

        delete objects;    //错误的用法

        后者相当于delete objects[0],漏掉了另外99个对象。(objects是数组首地址)

        

    再谈二者区别:

    1.       new自动计算需要分配的空间,而malloc需要手工计算字节数。

    2.       new是类型安全的,而malloc不是,比如:

    int * p = newfloat[2];   //编译时指出错误

    int * p =malloc(2*sizeof(float));  //编译时无法指出错误

    3.       new运算符由两步构成,分别是new 和 调用对象的构造函数

    new对应malloc,new调用时将调用要分配的类型的对象的构造函数,而malloc不能。

    在delete时,delete调用了释放内存的对象的析构函数,而free不能。

    所以我们不要用malloc/free来完成动态对象的内存管理,应该使用new/delete。由于内部数据类型的“对象”没有构造与析构过程,对它们而言malloc/free和new/delete是等价的。

          二者的联系:

                 既然new/delete的功能完全覆盖了malloc/free,为什么c++还要保留malloc/free呢?因为c++程序经常要调用c函数,erc程序只能使用malloc/free管理动态内存。如果使用free释放new创建的动态对象,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放malloc申请的动态内存,理论上程序不会出错,但该程序的可读性很差。

                 所以new/delete、malloc/free必须配对使用。

  • 相关阅读:
    Androi“.NET研究”d 源代码结构 狼人:
    Android UI“.NET研究”之困 横跨四个屏幕的战争 狼人:
    Win7 配“.NET研究”置Android开发环境 狼人:
    微“.NET研究”软“重启”Windows Phone 7 设计的经过 狼人:
    iOS开发库的族“.NET研究”谱介绍 狼人:
    文件匹配常用Linux命令小结
    functionclassAS sin函数小球运动
    持久化框架数据持久化框架(JPA)及其具体实现
    系统工程师Python工程师基础班
    设置虚拟机虚拟机中fedora上网配置bridge连接方式(图解)
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3343269.html
Copyright © 2011-2022 走看看