zoukankan      html  css  js  c++  java
  • char型字符串(数组)与string型字符串 指针与引用

    一、常指针:

    int *const p;    //指针不可改变,但是指针指向的数据可以改变。

    指向常量的指针:

    const int *p;    //指针可以改变,但是指针指向的数据不可以改变。

    指向常量的常指针:

    const int *const p;    //指针不可改变,且指针指向的数据也不可改变。

    引用就是别名,定义引用的同时必须要对引用进行初始化。

    二、利用引用返回多个值:

    引用就是别名,引用必须要初始化。

    #include "stdafx.h"
    #include <iostream>
    #include <cmath>
    using namespace std;
    void func(int &a,int &b,int &c);
    int main()
    {
        int a=1;
        int b=2;
        int c=3;
        cout<<"主函数,计算前。。。"<<endl;
        cout<<a<<"	"<<b<<"	"<<c<<endl;
        func(a,b,c);
        cout<<"主函数,计算后。。。"<<endl;
        cout<<a<<"	"<<b<<"	"<<c<<endl;
        return 0;
    }
    void func(int &a,int &b,int &c)
    {
        cout<<"func函数,计算前。。。"<<endl;
        cout<<a<<"	"<<b<<"	"<<c<<endl;
        a=a+1;
        b=(b)*(b);
        c=(c)*(c)*(c);  //
        cout<<"func函数,计算后。。。"<<endl;
        cout<<a<<"	"<<b<<"	"<<c<<endl;
    }

    三、删除空指针是不会报错的。

    int *p;
    p=new int;
    delete p;
    p=0;        //将指针赋值为空,假如没有这句,程序将崩溃。
    delete p;

    四、删除堆中指针后,只是释放了指针所指向的内存单元,指针仍然存在,且依然指向删除前的内存地址

    int *p=new int(11);
    cout<<"删除指针p前其指向的内存地址:"<<p<<endl;
    delete p;
    cout<<"删除指针p后其指向的内存地址:"p<<endl;

    程序输出结果:

    所以,为了保证程序的安全可靠,需要在delete p后加上p=0

    五、类的对象的this指针

    对象的this指针存储该对象的内存地址。

    #include "stdafx.h"
    #include <iostream>
    //#include <string>
    //#include <limits>
    using namespace std;
    
    class A
    {
    private:
        int i;
    public:
        void set(int x){this->i=x;cout<<"this指针的指向的内存地址为:"<<this<<endl;}
        //也可以直接写成i=x;
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        A a;
        a.set(11);
        cout<<"对象的内存地址为:"<<&a<<endl;
        return 0;
    }

    //运行结果如下图所示

    六、使用引用时容易犯错的地方

    临时变量生存期的问题

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    class A
    {
    private:
        int x;
    public:
        A(int i){x=i;}
        void get(){cout<<x<<endl;}
        ~A(){}
    };
    
    A &func();
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        A &ra=func();
        ra.get();
        return 0;
    }
    
    A &func()
    {
        A a(11);  //a为临时对象,func函数一旦结束,其生存周期也结束,立即销毁
        return a; 
    }

    可以看到最后返回的是一个随机数,这就是临时变量被提前删除的缘故

    若将func()函数前面的&去掉,则可正确返回a对象的成员变量的值。

    此时函数按值返回,对象a的副本生命周期会一直持续到main()函数结束。

    这是因为,作为引用的临时变量(即A &ra=func();),其生存周期不会短于该引用。

    七、按值传递传递的是变量的副本,按址传递,顾名思义肯定是传送的地址了。

    八、关于二维(数组)指针的一些理解问题

    int ** Ptr <==> int Ptr[ x ][ y ];
       int *Ptr[ 5 ] <==> int Ptr[ 5 ][ x ];
       int ( *Ptr )[ 5 ] <==> int Ptr[ x ][ 5 ];
       这里 x 和 y 是表示若干的意思。(转)

    测试代码:

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int main()
    {
        int (*p)[2]=new int[2][2]; 
        cout<<"指针数组的初始地址:"<<p<<endl;
        int i,j; 
        int a[2][2]={1,2,3,4}; 
        cout<<"二维数组的初始地址:"<<a<<endl<<endl;;
        cout<<"自定义赋值初始化指针数组!!!"<<endl;
        for (i=0;i<2;i++)  
            for (j=0;j<2;j++)  
            {   p[i][j]=i+j;  }
            //cout<<endl<<"使用二维数组初始化数组指针!!!"<<endl;
            //p=a; //使用二维数组初始化数组指针 
            cout<<"赋值后指针数组的地址:"<<p<<endl;
            for (i=0;i<2;i++) 
            {  
                for (j=0;j<2;j++)    
                    cout<<p[i][j]<<"	";  
                cout<<endl; 
            } 
            delete[] p;
            p=0; 
            return 0;
    }

    程序输出:自定义赋值初始化指针数组!

    下面对以上代码稍作修改,使用二维数组赋初值给指针数组。

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int main()
    {
     int (*p)[2]=new int[2][2]; 
     cout<<"指针数组的初始地址:"<<p<<endl;
     int i,j; 
     int a[2][2]={1,2,3,4}; 
     cout<<"二维数组的初始地址:"<<a<<endl<<endl;;
     /*cout<<"自定义赋值初始化指针数组!!!"<<endl;
     for (i=0;i<2;i++)  
     for (j=0;j<2;j++)  
     {   p[i][j]=i+j;  }*/
     cout<<endl<<"使用二维数组初始化数组指针!!!"<<endl;
     p=a; //使用二维数组初始化数组指针 
     cout<<"赋值后指针数组的地址:"<<p<<endl;
     for (i=0;i<2;i++) 
     {  
      for (j=0;j<2;j++)    
       cout<<p[i][j]<<"	";  
      cout<<endl; 
     } 
     //delete[] p;
     //p=0; 
     return 0;
    }

    程序输出:(delete[] p必须注释掉否则程序会崩溃。)

    九、复制构造函数

    #include <stdafx.h>
    #include<iostream>
    using namespace std;
    class A
    {
    private:
        int m,n;
    public:
        A(int i,int j){m=i;n=j;}  //构造函数
        A(A&temp){m=temp.m;n=temp.n;} //复制构造函数
        void print(){cout<<m<<"	"<<n<<endl;}
    };
    int main()
    {
        A a(2,3);
        a.print();
    
    
    
    
        A b(a);  //or A b=a;也可以
        b.print();
        return 0;
    }

    浅复制:(被复制对象的变量与复制对象的变量享有同样的内存空间)

    #include <stdafx.h>
    #include<iostream>
    using namespace std;
    class A
    {
    private:
        int *x;
    public:
        A(){x=new int;*x=5;}
        ~A(){delete x;x=0;}
        A (const A&temp){x=temp.x;}
        void display(){cout<<*x<<"	"<<&x<<endl;}
        void set(int i){*x=i;}
    };
    int main()
    {
        A *a=new A;
        a->display();
    
        A b(*a);
        b.display();
    
        a->set(10);
        a->display();
        b.display();
    
        b.set(15);
        a->display();
        b.display();
    
        //delete a;
    
        return 0;
    }

    深复制:(被复制对象的变量与复制对象的变量拥有各自独有的内存空间)

    #include <stdafx.h>
    #include<iostream>
    using namespace std;
    class A
    {
    private:
        int *x;
    public:
        A(){x=new int;*x=5;}
        ~A(){delete x;x=0;}
        A (const A&temp){x=new int;*x=*(temp.x);}
        void display(){cout<<*x<<"	"<<&x<<endl;}
        void set(int i){*x=i;}
    };
    int main()
    {
        A *a=new A;
        a->display();
    
        A b(*a);
        b.display();
    
        a->set(10);
        a->display();
        b.display();
    
        b.set(15);
        a->display();
        b.display();
    
        delete a;
    
        return 0;
    }

    十、char型字符串(数组)与string型字符串

    如:char man[100];//当使用cin来输入字符串时,遇到空格(即空字符0 or ‘’)的话,字符串输出时就从此截断。

    比如输入hello world,那么输出只有hello。

    C++提供了一种简单高效的方法来解决上述问题,char man[]={“hello world”},或者char man[]="hello world",此时再输出就正常了。

    char型字符串时C语言时的风格,在C++时代产生了C++风格的字符串,string型字符串。使用时必须添加string头文件。

    由于string是一个类,那么string str;//str就可以看成是string类的一个对象,该对象可以调用string类的各种成员函数。

    1、char型字符串有以下3种形式

    char c[12]="study"    //字符数组

    “study”                    //未命名字符串

    char *p="study"        //指向未命名字符串的指针

    以上3种类型只有第一种所指向的字符串可以改变。

    #include "stdafx.h"
    #include <iostream>
    #include <string>
    using namespace std;
    
    char *get(char *str);
    
    int main()
    {
        char name[20];
        char *name1;
        cout<<"请输入您的名字:"<<endl;
        cin>>name;
        name1=get(name);
        cout<<"您的名字是:"<<name1<<endl;
        delete []name1;
        name1=get("Jack");
        cout<<"您的名字是:"<<name1<<endl;
        delete []name1;
        char *name2="Mike";
        name1=get(name2);
        cout<<"您的名字是:"<<name1<<endl;
        delete []name1;
        return 0;
    } 
    char *get(char *str)
    {
        char *p=new char[strlen(str)+1];  //这里如果用sizeof函数,程序会崩溃
        strcpy(p,str);
        cout<<p<<endl;
        return p;
    }

    2、C的结构体与C++的类的唯一区别在于前者的成员变量默认是公有的,而类的成员变量默认是私有的。

    对于公有成员变量,我们可以像使用成员函数那样使用成员变量。

  • 相关阅读:
    数据挖掘读书笔记-数据库系统技术
    数据挖掘读书笔记-典型的数据挖掘系统
    数据挖掘读书笔记-数据挖掘的概念
    数据产品经理做什么?
    从浏览器渲染的角度谈谈html标签的语义化
    Mozilla推动互联网成为游戏发展的强有力平台
    css知识点
    css变形 transform
    跟css背景有关的属性
    css颜色表示的方式
  • 原文地址:https://www.cnblogs.com/audi-car/p/4442849.html
Copyright © 2011-2022 走看看