1、数组是具有一定顺序关系的若干对象的集合体,组成数组的对象称为该数组的元素
数组元素在内存中顺序、连续存储,C++中二维数组被当作一维数组的数组,例如int m[2][3]所定义的m看作是大小为2,每个元素都是一个大小为3、类型为int 的数组
数组的初始化就是在声明数组时给部分或全部元素赋初始值,当指定的初值个数小于数组大小时,剩下的数组元素会被以0赋值。
数组也可以被声明为常量,例如:const float fa[5]={1.0,2.0,3.0};表明该数组中每个元素都被当作常量对待,也就是说它们在初始化后皆不可以改变,声明为常量的数组,必须给定初始值。
使用数组名传递数据时,传递的是地址。把数组作为参数时,一般不指定第一维的大小
2、使用数组名作为函数参数的例子
#include<iostream>
using namespace std;
void roeSum(int a[][4],int nRow){ //计算二维数组a每行元素的值的和,nRow是行数
for(int i=0;i<nRow;i++){
for(int j=1;j<4;j++)
a[i][0]+=a[i][j];
}
}
int main(){
int table[3][4]={{1,2,3,4},[2,3,4,5},{3,4,5,6}}; //声明并初始化数组
for(int i=0;i<3;i++){ //输出数组元素
for(int j=0;j<4;j++)
cout<<table[i][j]<<" ";
cout<<endl;
}
rowSum(table,3); //调用子函数,计算各行的和
for(int i=0;i<3;i++)
cout<<"Sum of row"<<I<<"is"<<table[i][0]<<endl;
return 0;
}
3、与基本类型数组一样,在使用对象数组时也只能引用单个数组元素,每个数组元素都是一个对象,通过这个对象,可以访问到它的公有成员,一般形式是:数组名[下标表达式].成员名
如果在声明数组时给每一个数组元素指定初始值,在数组初始化过程中就会调用形参类型相匹配的构造函数,例如:
Location a[2]={Location(1,2),Location(3,4)};
在执行时会先后两次调用带形参的构造函数分别初始化a[0]和a[1],如果没有指定数组元素的初始值,就会调用缺省构造函数,例如:Location a[2]={Location(1,2)};
4、具有静态生存期的变量,是在程序运行时遇到变量声明语句时被分配了内存空间,具有动态生存期的变量是在程序运行时遇到变量声明语句时被分配内存空间。在变量获得内存空间的同时,变量名也就成为相应内存空间的名称,在变量的整个生存期内都可以用这个名字访问该内存空间。
5、指针变量是用于存放内存单元地址
“*”称为指针运算符,也称为解析,表示获取指针所指向的变量的值
“&”称为取地址运算符,是一个一元运算符,用来得到一个对象的地址
int *p=&i;取i的地址赋值给ptr
一个数组,可以用它的名称来直接表示它的起始地址,数组名实际上就是一个不能被赋值的指针,即指针常量。
不能声明void类型的变量,但可以声明void类型的指针(一般只在指针所指向的数据类型不确定时使用)
二者等价:
1.
int *p;
p=0;
2.
int *p=NULL;
6、标准库函数begin和end,这两个函数定义在iterator头文件中,begin函数返回指向数组首元素的指针,end函数返回指向数组尾元素下一位置的指针
7、例题(读入三个浮点数,将整数部分和小数部分分别输出)
#include <iostream>
using namespace std;
//将实数x分成整数部分和小数部分,形参intPart、fracPart是指针
voidsplitFloat(float x,int *intPart,float *fracPart){
*intPart=static_cast<int>(x); //取x的整数部分
*fracPart=x-*intPart; //取x的小数部分
}
int main()
{
cout<<"Enter 3 float point numbers:"<<endl;
for(int i=0;i<3;i++){
float x,f;
int n;
cin>>x;
splitFloat(x,&n,&f); //变量地址作为实参
cout<<"Integer Part="<<n<<"Fraction Part="<<f<<endl;
}
return 0;
}
8、指针型函数的一般定义形式:
数据类型 *函数名(参数表)
{
函数体
}
9、对象指针是用于存放对象地址的变量(对象所占据的内存空间只是用于存放数据成员的,函数成员不在每一个对象中存储副本)
声明对象指针的一般语法形式为:
类型 *对象指针名;
例如:
Point *pointPtr; //声明Point类的对象指针变量pointPtr
Point p1; //声明Point类的对象p1
PointPtr=&p1; //将对象p1的地址赋值给pointPtr,使pointPtr指向p1
10、例题(使用指针来访问Point类的成员)
#include <iostream>
using namespace std;
class Point{
public:
Point(int x=0,y=0):x(x),y(y){}
int getX() const{return x;}
int getY() const{return y;}
private:
int x,y;
};
int main(){
Point a(4,5); //定义并初始化对象a
Point *p1=&a; //定义对象指针,用a的地址将其初始化
cout<<p1->getX()<<endl; //利用指针访问对象成员
cout<<a.getX()<<endl; //利用对象名访问对象成员
11.this指针:是一个隐含于每一个类的静态成员函数中的特殊指针(包括构造函数和析构函数),它用于指向正在被成员函数操作的对象,它明确指出了成员函数当前所操作的数据所属的对象。
它实际上是一个隐含于每一个类的非静态成员函数中的特殊指针。在成员函数中,可以使用*this来标识正在调用该函数的对象。
提示:当局部作用域中声明了与类成员同名的标识符时,对该标识符的直接饮用代表的是局部作用域中所声明的标识符,这时为了访问该类成员,可以通过this指针。
对 数据成员指针赋值的一般语法为:
指针名=&类名::数据(函数)成员名;
对类成员取地址时,也要遵守访问权限的约定,也就是说,在一个类的作用域之外不能对它的私有成员取地址
访问数据成员时,这种结合可通过以下两种语法形式实现:
对象名.*类成员指针名 对象指针名->*类成员指针名
常成员函数与普通成员函数具有不同的类型,因此能够被常成员函数赋值的指针,需要在声明时明确写出const关键字。
12、例子(访问对象的公有成员函数的不同方式)
#int main(){
Point a(4,5); //定义对象A
Point *p1=a; //定义对象指针并初始化
int (Point::*funcPtr)()const=&Point::getX; //定义成员函数指针并初始化
cout<<(a.*funcPtr)()<<endl; //使用成员函数指针和对象名访问成员函数
cout<<(p1->*funcPtr)()<<endl; //使用成员函数指针和对象指针访问成员函数
cout<<a.getX()<<endl; //使用对象名访问成员函数
cout<<p1->getX()<<endl; //使用对象指针访问成员函数
return 0;
}
13、运算符new:动态内存分配(动态创建堆对象):new 数据类型(初始化参数列表);
int *point;
point=new int(2);
动态分配了用于存放int类型的内存空间,并将初值2存入该空间,然后将首地址赋给指针Point。
若不希望设定初值,可将括号去掉;若保留括号,但括号中不写任何数值,则表示用0初始化
运算符delete用来删除由new建立的对象,释放指针所指向的内存空间,格式为:
delete 指针名;
对于用new建立的对象,只能使用delete进行一次删除操作。
14、vector不是一个类,而是一个类模版,本章只需记住形式上vector的使用方式:
vector<元素类型>数组对象名(数组长度);
vector定义的数组对象的所有元素都会被初始化,若指定则改为(数组长度,元素初始值)