zoukankan      html  css  js  c++  java
  • 定义一个变长数组和常量引用参数

    定义变长数组: 

    int len;
    cin>>len;
    int *p=new int[len];
    for(int i=0;i<len;i++)
        cin>>p[i];
    for(int i=0;i<len;i++)
       cout<<p[i];
    delete[] p;
    return 0;
    用指针p指向new动态分配的长度为len*sizeof(int)的内存空间   
    如果使用 int p[len]; 错误,len的大小不确定在编译阶段。
    如果使用 int p[]=new int[len]; 错误,new开辟了一段内存空间返回的是内存的首地址,不能从int * 到 int[] 型。

    定义一个变长的字符数组:
    char *p=new char[len];

    如果使用 char *p="abc"; 为字符串常量,p所指向的值不能再改变。

    用 vector 实现变长数组:

    int len;
    cin>>len;
    vector <int> arry(len);
    for(int i=0;i<len;i++)
        cin>>array[i];

    类似java中vector 和 ArrayList 变长数组。但是java中有自动地垃圾回收机制,c++中需要调用析构函数释放内存:~vector().

    实现N维数组:

    //c 语言
    int row,col;
    scanf("%d",&row);
    scanf("%d",&col);
    int **a;
    a=(int **)malloc(sizeof(int *)*row);
    for(int i=0;i<row;i++)
        *(a+i)=(int *) malloc(sizeof(int) *col);
    for(int i=0;i<row;i++)
        for(int j=0;j<col;j++)
        scanf("%d",&a[i][j]);
    //c++指针实现
    int row,col;
    cin>>row;
    cin>>col;
    int **p=new int *[row];
    for(int i=0;i<row;i++)
        p[i]=new int[col];
    for(int i=0;i<row;i++)
    {
        for(int j=0;j<col;j++)
        {
            cin>>p[i][j];
            cout<<setw(6)<<p[i][j];
        }
        cout<<endl;
    }

    for(int i=0;i<row;i++)
    delete [] p[i];
    delete [] p;

    如果有一维是未知的,必须在运行时使用操作符new来创建数组。

    //C++ vector 实现

    int row,col;
    cin>>row;
    cin>>col;
    vector<vector<int> > array(row,vector<int> (col));
    for(int i=0;i<row;i++)
    for(int j=0;j<col;j++)
    cin>>array[i][j];
    return 0;

     
    常量引用:
    template <class T>
    T cal(const T & a, const T &b, const T &c)
    return a+b+b*c+(a+b+c)/(a+b)+4;

    关键字const 来表示函数是不可修改引用参数的值;表明用户不能修改实际参数,相当于值传递对于简单数据类型 int,float,char,内置容器。 但值传递函数参数将会初始化为实参的拷贝,调用者得到的也是返回值的一个副本。 这些拷贝是通过调用对象的拷贝构造函数完成的,正是这一方法的调用使得拷贝的代价可能会很高。对于其他数据类型含模板类型,当函数不能修改实际参数的数值时采用常量引用参数。来减少代价和避免截断。

    减少代价eg:

    class Person{
    string name,address;
    };
    
    class Student: public Person{
    string schoolName,schoolAddress;
    };

    如果定义函数

    bool validateStudent(Student s);

    调用:

    Student p;

    bool check=validateStudent(p);

    在调用过程中进行了6次函数调用:Person的拷贝构造函数,student 的拷贝构造函数,name,address,schoolName,schoolAddress的拷贝构造函数。

    而使用常量引用:

    bool validateStudent(const Student& s);

    以引用的方式传递,不会构造对象。

    避免截断:

    由于类型限制,子类对象被传递时只有父类部分被传入函数。

    class Window{
    public: 
        string name() const;
        virtual void display() const;
    };
    
    class WindowWithScrollBars:public Window{
    public:
        virtual void display()const;
    };
    
    void printAll(Window w)
    {
        cout<<w.name();
        w.display();
    }
    WindowWithScrollBars wb;
    printAll(w);

    当调用printAll时,参数类型从WindowWithScollBars 隐式转换为Window。此过程是通过调用window的拷贝构造函数进行的。结果是函数中w为一个Window对象,并不会调用多态子类函数display。

    然而使用引用:

    void printAll(const Window & w)
    {
        cout<<w.name();
        w.display();
    }

    引用是通过指针来实现的

  • 相关阅读:
    sqhhb
    12333
    12

    今日份
    12
    彻底理解 Cookie、Session、Token
    https原理
    12312
    uiower
  • 原文地址:https://www.cnblogs.com/fanhaha/p/7066853.html
Copyright © 2011-2022 走看看