在介绍之前,我们先了解一下关于数组名的知识。
数组名
代表这段内存首地址
回忆一下指针的定义,这数组名不就是指针吗,我们试着 *** 作一下
int array[3]={1,2,3};
for(int i=0;i<3;i++)
{
printf("%d\t%d\n",array[i],*(array+i));
printf("%p\t%p\n",&array[i],&*(array+i));
}
可以看到,数据和地址都一致。
//对于array(数组名)
//正常 *** 作: 直接存储数组的首地址
//直接把指针当作数组名就可以了
//非正常 *** 作:指向其他元素开始 *** 作数组
所以,对应指针(一级指针)也可以 *** 作数组
int array[3]={1,2,3};
int* p=array;
for(int i=0;i<3;i++)
{
printf("%d\t",p[i]);//对于这种方法我比较推荐,好理解,也可以用指针偏移
//printf("%d\t",*(p+i));
}
ptintf("\n");
*p等效于p[0] 取当前地址对应内存中的值
但是数组名的地址是不能更改的,这也是与指针的区别
int test[3] = { 1,2,3 };
int* pT = &test[2];
printf("%d\n", pT[0]);//指针的[0]并不指数组第几个元素
printf("%d\n", pT[-1]);//pT[-1]等效于*(pT-1)
printf("%d\n", pT[1]);//未知量,垃圾值
指针 *** 作二维数组
一级指针 *** 作二维数组
-
二维数组(举例为array[2] [3])在内存中是连续的,而二维数组的数组名是个数组指针(数组指针的首地址)。
-
对于每行的首地址为数组名[i],例: array[i]
-
使用数组名的偏移方式与一维数组不太一样
光看着可能不太明白,我们直接 *** 作
int array[2][3]={1,2,3,4,5,6};
int* p=&array[0][0];
/*
注:
二维数组的类型为:int (*)[3],即数组指针
所以数组名(二维数组)是个指向数组的指针,不是一级指针
*/
printf("%p\n",array);
printf("%p\n",&array[0][0]);
printf("%p\n",array+1);
printf("%p\n",p+1);
粗略分析一下
-
array与&array[0] [0]输出的值相同,即两者地址相同
-
(array+1)-array 的值为C(0x64-0x58=0xC,转十进制为12,即12个字节),正好是一行元素所占字节数
-
同理,p+1对于p(即array[0] [0]) 偏移了4个字节(0x5c-0x58=0x4)
所以对于二维数组不能直接用数组名赋给一级指针
直接点就是,有几个元素就加几
array[i] [j]==*(p+n) (n=i *每行元素个数+j)
for(int i=0;i<6;i++)
{
printf("%d\t",*(p+i));
}
printf("%d\n",array[1][2]);
printf("%d\n",*(p+(1*3+2)));
数组指针 *** 作二位数组
数组指针
-
指向数组的指针
-
定义时,括号不能少
-
只要指向首地址,可以直接当作数组名使用
int array[2][3]={1,2,3,4,5,6};
int (*pArray)[3]=NULL;//(*pArray)可以理解为数组名
pArray=array;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", pArray[i][j]);
}
printf("\n");
}
还有不一样的用法(不推荐)
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", *(*(pArray + i) + j));//或者printf("%d\t",*(pArray[i]+j));
//printf("%d\t",*((pArray+i)[0]+j));
//printf("%d\t",((pArray+i)[0]+j)[0]);
}
printf("\n");
}
数组指针也可以作为函数参数
void printArray(int (*p)[3],int row,int col)
//等效void printfArray(int p[][3],int row,int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf("%d\t", p[i][j]);
}
printf("\n");
}
}
指针数组
-
指针数组也可以控制二维数组
-
就是多个指针
-
一般用于 *** 作字符串
char str[3][20] = {"ILoveYou","IMissYou","abc"};
char* pstr[3] = {str[0],str[1],str[2]};
//每个pstr[i]都是一级指针
for (int i = 0; i < 3; i++)
{
puts(pstr[i]);
}
二级指针
-
用于存放一级指针的地址
-
同,N级指针是用来存放N-1级指针的地址
-
定义
类型说明符 ** 名称
int* p=NULL;
int** pp=&p;
//几个*就是几级指针
看一下实例
int a=1;
int* p=&a;
int** pp=&p;
printf("%d\t%d\n",*p,p[0]);
printf("%d\t%d\n",**pp,*pp[0]);//或者pp[0][0],类似于二维指针但不同于二维数组
不能纯粹地当作二维数组来用
有的编译器可以,但是在C++中是错的
下期我会整合一下关于内存的知识点,最后感谢您能阅读我的博客,谢谢。 <\u>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)