对于一维数组a[i](a[i]类型不为char),a表示数组的首地址,即a=&a[0]。
int a[10]; cout<对于字符串数组,使用输出数组名称指令则会直接输出整个字符串数组。
char str[10]={'1','2','3','4'}; cout<综上,cout遇到输出字符类型的地址时,不会输出地址,而是输出该地址上的字符。所以如果想输出字符串数组的地址,需要把指针改为其他类型,如char或int。
指针存在类型 ,如int *p,p是int类型的指针,不可以指向double类型的地址
int *p p=p+1 加上了一个int的字节,即加了四个字节。
char *p p=p+1 加上了一个char的字节,即加了一个字节。int a[10]={1,2,3}; cout<<*a<指针存在着运算,此处说明一维数组分配的是一段连续的内存,可以通过某种运算公式得到地址。如要求a[5],地址即为a+5。
对于二维数组,以a[10][20]为例,其实分配的内存也是连续的一段,故可以通过某个固定的运算公式来得到地址。
如要求a[5][5],地址即为a+5*20+5。其中20为第二维的长度。
对多维数组也是如此。很容易发现,地址的计算与一维的数目无关,这也是为何将数组作为参数被函数调用时不需要写明第一维的长度,但需写明除第一维外所有维度长度的原因。二维数组的数组名也是表示数组的地址,但与一维数组不同的是,它表示的数组中的每一个元素都是一个数组的地址。
int a[10][20]; a[0][0]=1; cout<<(*a)<在数组a中,每一个元素a[i]都代表着一个数组的地址,对应着二维数组的一行。因此,a与一维数组的首地址不同,如果想用一个指针p指向a,不可以运用与一维数组相同的方式。
int a[10][20]; //int *p=a; 编译报错 int (*q)[20]=a;//编译成功 int (*t)[20]=&a[0];//编译成功 int *p=a[0];//编译成功,此时p与q指向的地址相同,都为a[0]此处的(*q)[20]意在告诉编译器,a所指向的数组中的元素都是一个长度为20的数组。
int a[10][20]; int (*q)[20]=a; cout<指针q的移动均是跨行移动,因为a在其指向的数组上,a[1]与a[2]之间分配的内存刚好相差一个第二维的长度,因此q每加1,相当于增加了20*4个字节,在十六进制下为50。而a[0]每移动1,其地址增加4个字节。 指针数组+二重指针定义:
如果一个数组中的所有元素保存的都是指针,那么我们就称它为指针数组。
指针数组的定义形式一般为:
dataType *arrayName[length];
注意区别指向二维数组的指针(在上文为a)的定义为
dataType (*arrayName)[length]
int a=1,b=2,c=3; int *p[5]={&a,&b,&c};//相当于p[0]=&a cout<<*(p[1]);//输出2对于指针数组,同样是一个数组,如果想要再使用一个指针p指向该数组的首地址,那指针p即是指针数组的指针,即是一个二重指针。
对二重指针的定义为
dataType **(arrayName);
具体使用举例
int a=1,b=2,c=3; int *p[5]={&a,&b,&c};//相当于p[0]=&a int **q=p; cout<<*(q)<需要注意的是:
二重指针代表着这个指针指向的数组的类型是一个指针数组,即是数组中的每一个元素都是一个指针。
而二维数组中,数组名a作为地址,对应的数组的每一个元素是二维数组每一行的首地址(可认为是地址数组)。
故不可直接用二重指针指向a所在的地址。int a[10][20]; int (* q)[20]=a;//正确 int **p=a;//错误指针数组中的每一个指针指向地址时是相互独立的。上文中a指向的数组中a[1]、a[2]是对应的二维数组的每一行的地址。我们可以对每一行分别用一个指针指向这一行的首地址,将一个二维数组所用的指针放进一个数组中,就得到了一个指针数组。
如果先定义了二维数组,再用指针数组去指向每一行的首地址,那么指针数组中的指针指向的地址便是连续的。int *p[3]; int a[3][2]; for(register int i=0;i<3;i++){ p[i]=a[i];//p[i]=&a[i][0]; } cout<
但如果先定义了指针数组,再让每一个指针去指向一个一维数组从而构成一个二维数组,那么每一个指针的内存分配就不一定连续。
int *q[5]; int a[2],b[2],c[2]; q[0]=a; q[1]=b; q[2]=c; cout<举一些函数对二维数组调用的例子
void BubbleSort(char a[10][20]);//正确 void Bubble(char a[][20], int n);//正确 void Bubble(char a[10][], int m);//错误,关键在除第一维之外的维度 void Bubble(char * a[10], int m);//正确 void Bubble(char a[][], int n, int m);//错误,理由如上 void Bubble(char ** a, int n, int m);//正确 void Bubble(char * a[], int n, int m);//正确,第一维不需要上文中第4、6、7种调用方法与第1、2种所用的内存分配方法不同,在调用时有着不同的调用方式。
void dfs(char **a){ return; } void dfs1(char *a[]){ return; } int main(){ char *p[5]; dfs(p); dfs1(p); }指针的内容较为繁杂,故写下这篇文章便于自身理解,也希望各位读者可以对其提出宝贵的意见。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)