定义一个变长数组和常量引用参数
定义变长数组:
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(); }
引用是通过指针来实现的