1、指针运算
利用数组元素在内存中连续存储的特点,通过加减运算(算术运算)修改地址值可以让指针变量指向不同的数组元素;通过比较地址值的大小(关系运算),可以确定不同数组元素之间的位置次序。指针类型就是地址类型,凡是涉及内存地址的运算统称为指针运算。
下面列举几种通过改变指针指向的语句:
int a[5] = {0,1,2,3,4}; int *p = &a[0];//int *p = a; *(p+1) //语法正确,表示数组第1个元素的值(这里注意不是第0个元素的值) *(a+1) //语法正确,效果同上 *(a++) //语法错误,a是数组,为不可修改的左值 *(p++) //语法正确:表示取出数组第0个元素的值,然后在让p指向第一个元素的地址 *(a++); *(&a++) *(a[0]++) *(&a[0]++) *(&p++); *(p[0]++); *(&p[0]++);//以上这7种均为语法错误,无法取出数组第0个元素的值
下面列举几种通过指针获取数组值的语句:
int a[6] = { 0,1,2,3,4,5 }; int* p=a; p = a; p = &a[0]; //以上三种给指针赋值方法均正确 cout << "a = " << a << endl; cout << "&a = " << &a << endl; cout << "&a[0] = " << &a[0] << endl; cout << "p = " << p << endl; cout << "*a = " << *a << endl; cout << "*p = " << *p << endl; cout << "a[0] = " << a[0] << endl; cout << "p[0] = " << p[0] << endl; cout << "*a[2] = " << a[2] << endl; cout << "*p[2] = " << p[2] << endl; cout << "*(a+0) = " << *(a + 0) << endl; cout << "*(p+0) = " << *(p + 0) << endl; cout << "*(a+1) = " << *(a + 1) << endl; cout << "*(p+1) = " << *(p + 1) << endl;View Code
结果如下:
a = 000000F86A7CF888 &a = 000000F86A7CF888 &a[0] = 000000F86A7CF888 p = 000000F86A7CF888 *a = 0 *p = 0 a[0] = 0 p[0] = 0 *a[2] = 2 *p[2] = 2 *(a+0) = 0 *(p+0) = 0 *(a+1) = 1 *(p+1) = 1View Code
2、指针的算数运算
1)指针类型(非void)可以与整数进行加减运算。当指针p指向数组某一元素时,p+n指向数组该元素后面的第n个元素,p-n指向该数组元素前面的第n个元素。
2)两个相同类型的指针可以进行减法运算,p1指向数组某一元素,p2指向数组另一元素,p1-p2表示两元素下标之差。
3)void型指针不能进行算术运算。C++中void类型占多少字节并没有定义,sizeof(void)是语法错误。
3、指针的关系运算
如果指针指向同一数组当中的元素,则通过比较他们的大小可以确定其所指向数组元素之间的位置次序。
int a[5] = {0,1,2,3,4}; int *p = &a[0]; for(p=&a[0];p<=&a[5];p++) cout<<*p<<"," //以上代码可完成数组的遍历
4、动态内存分配(new)
1)单个变量的动态分配与释放
指针变量名 = new 数据类型(初始值);
delete 指针变量名;
举例:
int *p = new int(10);//动态分配变量时进行初始化,注意new和malloc进行动态分配空间的区别,面试经常会被问到?int *p = (int *)malloc(sizeof(int)); delete p;//将动态分配的内存释放掉
2)一维数组的动态分配与释放(注:动态分配的数组变量不能初始化)
指针变量名 = new 数据类型[表达式];
delete [ ]指针变量名;
举例:
int *p = new int[5];//动态分配一个int型一维数组变量,包含5个数组元素。 *(p+1)=10;//给数组第一个元素赋值 delete [ ]p;//将给数组动态分配的内存释放掉
3) 指针数组
C++中定义了一个指针类型的数组,其每个元素都是指针变量,这就是指针数组。
举例:int *pi[3]; //定义int型指针数组pi,每个数组元素都是一个int型指针变量
指针数组可应用于二位数组的动态分配。二维数组的灭意航都可以理解为是一个以为数组,依次为每一行分配一个一维数组,并用指针数组来保存各行的首地址,这样就可以实现二位数组的动态分配。
举例:
int *p[3]; int m; for(m=0;m<3;m++) p[m]=new int[5];//动态分配一个一维数组,用指针数组指向的二位数组可以不连续 for(m=0;m<3;m++) delete []p[m];//循环逐行释放每一行动态分配的一维数组
思考:二重指针如何进行动态分配?
答案请看上一篇结尾处。