出现原因
数组
- C++的数组类型为同类型对象的组织提供了一种有效的形式
指针
- 实现直接使用地址来访问内存功能 (C++从C继承来的一个重要特征)。应用指针,可以方便地处理连续存放的大量数据,以比较低的代价实现函数间的大量数据共享,灵活地实现动态内存分配。
概念
数组
数组是具有一定顺序关系的若干对象的集合体,组成数组的对象称为该数组的元素。
注意:
1.数组元素的下标表达式可以是任意合法的算术表达式,其结果必须是整数
2.数组下标值必须在确定的上下界范围内,否则出现数组越界错误
指针
- 指针:指针是C++从C中继承过来的重要数据类型,提供了一直较为直接的地址操作手段,是一种专门用来存放内存单元地址的变量类型
- 指针变量:具有指针类型的变量称为指针变量,指针变量是用于存放内存单元地址的
操作
数组的存储和初始化
- 数组:数组元素在内存中是顺序、连续存储的。数组元素在内存中占据一组连续的存储单元,逻辑上相邻的元素在物理地址上也是相邻的。一维数组简单按照下标顺序,连续存储;多维数组也是顺序连续存储。
- 数组初始化:在声明数组时给部分或者全部元素赋初始值。对于基本类型数组,给数组元素赋值;对于对象数组,考虑构造函数情况。
- 数组作为函数参数:使用数组名传递数据时,传递的是地址
注意:
1. 当指定初始值个数小于数组大小时,剩下的数组元素会被赋予0
2. 若定义数组时没有指定任何一个元素的初始值,对于静态生存期的数组,每个元素仍会被赋0值;但对动态生存期的数组,每个值都不确定。
3. 把数组作为参数时,(一般)不指定一维大小,即使指定,也被忽略
4. 当一个数组中的元素被删除时,系统会调用析构函数完成扫尾工作!
指针
与地址相关的运算*
和&
*
称为指针运算符,也称解析,表示指针所指向的变量值
&
称为取地址运算符,得到一个对象的地址
int *p; //声明p是一个int型指针
cout<<*p; //输出指针p所指向的内容
int a,b;
int*pa,*pb=&b;
pa=&a;
/* & 在给变量赋值时出现在等号右边或在执行语句中作为一元运算符出现时,表示取对象地址*/
指针的赋值
- 定义一个指针,只是得到一个用于存储地址的指针变量,但是变量中没有明确的值,其地址不确定!定义之后必须赋值才能引用。
格式: 存储类型 数据类型 *指针名=初始地址 赋值:对象类型和指针类型一致(用 & 获取地址) 数组名实际上是一个不能被赋值的指针—指针常量
- 内存理解:
int i; int *ptr=&i;
- 注意:
(1) 声明指向常量的指针,不能通过指针改变所指对象的值
int a;
const int*p=&a; //p是指向常量的指针
int b;
p=&b; //修改p本身的地址
*p=1; //编译出错!不能修改p所指对象
(2)声明指针类型的常量,不能修改指针本身的值,可以修改指向的对象
int *const p=&a;
p=&b; //p为常量指针,指针本身不能修改
(3)一般情况,指针只能在相同类型中互相赋值。特殊类型:void类型指针,可以存储任何类型的对象地址,任何类型指针都可以赋值给void类型指针变量
void *p; //声明void类型的变量
int i=5;
p=&i; //void 类型指针指向整形变量
指针的运算
-
算术运算:“指针++”、“指针–”表示指针当前位置下一个或者前一个数据的地址
*(p1+n1)表示p1当前所指位置后方第n1个数的内容,也可以写作p1[n1],减法同理
内存实现机制:
注意:
对于一个独立变量的地址,如果进行算术运算,对其结果指向的地址进行操作,可能会意外破坏该地址中的数据或者代码,在对指针进行运算时,要确保运算结果所指向的地址是程序中分配的内存。 -
关系运算:指的是相同类型数据的指针之间进行的关系运算。不同类型的指针之间活指针与非0证书之间的关系运算是无意义的。
但是指针可以跟整数0比较,0专用于表示空指针,也就是一个不指向任何有效地址的指针,给指针赋0就表示空指针int *p; //一个int型指针 p=NULL; //声明为空 // 或者 int *p=NULL
注意: 1. NULL是一个在很多头文件都定义的宏,定义成0 2. 在声明一个指针的时候,要等到程序运行到某个时间才给这个指针赋值,在这没有被赋值的时间内,其中的值不确定,如果误用会造成不可预见的错误 3. 如果不便用一个有效地址给一个指针变量初始化,那么把指针指向NULL
用指针处理数组
*array=array[0] ;*(array+3)=array[3]
指针数组
一个数组的每个元素都是指针,int *pa[3]
,(必须先赋值后引用)看图解
int *pa[3]; //[]的优先级比*高
int l1[]={1,0,0};
int l2[]={0,1,0};
int l3[]={0,0,1};
pa={l1,l2,l3}; // 指针赋值
二维数组 array[3][4]
的每个值可以由*(*(array+i)+j)
访问,表示第 i 行第 j 列
指针作为函数参数
指向函数的指针
对象指针
- 对象指针:通过对象地址访问一个对象
- this指针:隐含于每一个类的非静态成员中的特殊指针(包括构造和析构),用于指向正在被成员函数操作的对象,同时又是一个指向常量的指针,用
*this
标识正在调用该函数的对象 - 指向类的非静态成员指针
。。。待补充
总结一下数组和指针的区别: