在介绍之前,我们先了解一下关于数组名的知识。
数组名
代表这段内存首地址
回忆一下指针的定义,这数组名不就是指针吗,我们试着操作一下
int array[3]={1,2,3};
for(int i=0;i<3;i++)
{
printf("%dt%dn",array[i],*(array+i));
printf("%pt%pn",&array[i],&*(array+i));
}
可以看到,数据和地址都一致。
//对于array(数组名)
//正常操作: 直接存储数组的首地址
//直接把指针当作数组名就可以了
//非正常操作:指向其他元素开始操作数组
所以,对应指针(一级指针)也可以操作数组
int array[3]={1,2,3};
int* p=array;
for(int i=0;i<3;i++)
{
printf("%dt",p[i]);//对于这种方法我比较推荐,好理解,也可以用指针偏移
//printf("%dt",*(p+i));
}
ptintf("n");
*p等效于p[0] 取当前地址对应内存中的值
但是数组名的地址是不能更改的,这也是与指针的区别
int test[3] = { 1,2,3 };
int* pT = &test[2];
printf("%dn", pT[0]);//指针的[0]并不指数组第几个元素
printf("%dn", pT[-1]);//pT[-1]等效于*(pT-1)
printf("%dn", pT[1]);//未知量,垃圾值
指针操作二维数组
一级指针操作二维数组
二维数组(举例为array[2] [3])在内存中是连续的,而二维数组的数组名是个数组指针(数组指针的首地址)。
对于每行的首地址为数组名[i],例: array[i]
使用数组名的偏移方式与一维数组不太一样
光看着可能不太明白,我们直接操作
int array[2][3]={1,2,3,4,5,6};
int* p=&array[0][0];
printf("%pn",array);
printf("%pn",&array[0][0]);
printf("%pn",array+1);
printf("%pn",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("%dt",*(p+i));
}
printf("%dn",array[1][2]);
printf("%dn",*(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("%dt", pArray[i][j]);
}
printf("n");
}
还有不一样的用法(不推荐)
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%dt", *(*(pArray + i) + j));//或者printf("%dt",*(pArray[i]+j));
//printf("%dt",*((pArray+i)[0]+j));
//printf("%dt",((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("%dt", 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("%dt%dn",*p,p[0]);
printf("%dt%dn",**pp,*pp[0]);//或者pp[0][0],类似于二维指针但不同于二维数组
不能纯粹地当作二维数组来用
有的编译器可以,但是在C++中是错的
下期我会整合一下关于内存的知识点,最后感谢您能阅读我的博客,谢谢。



