用代码理解记忆
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#define ROW 5
#define COL 8
void test(int row, int col, int ***p)
{
int i;
/*
*printf("&p : %p\n", &p);//四级指针
*printf("p : %p\n", p);//三级指针
*printf("*p : %p\n", *p);//二级指针
*/
*p = (int **)malloc(sizeof(int *) * row);
if (NULL == *p)
{
printf("malloc false!\n");
return ;
}
/*
*printf("*p : %p\n", *p);//二级指针
*printf("**p : %p\n", **p);//一级指针
*/
for (i = 0; i < row; i++)
{
//*((*p) + i)
(*p)[i] = (int *)malloc(sizeof(int) * col);
if (NULL == (*p)[i])
{
while (i--)
{
free((*p)[i]);
}
free(*p);
return ;
}
}
return ;
}
int **test1(int row, int col)
{
int i;
int **p = NULL;
p = (int **)malloc(sizeof(int *) * row);
for (i = 0; i < row; i++)
{
p[i] = (int *)malloc(sizeof(int) * col);
}
return p;
}
int main(void)
{
int i, j;
int **p = NULL;
test(ROW, COL, &p);
//p = test1(ROW, COL);
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
p[i][j] = rand() % 100;
}
}
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
printf("%d ", p[i][j]);
}
putchar(10);
}
//销毁
for (i = 0; i < ROW; i++)
{
free(p[i]);
}
free(p);
return 0;
}
如果指向指定的数组呢
#include<stdio.h>
#include<stdlib.h>
void test(int ***p,int row,int col)
{
//注释的为错误思路
/*//p=(int ***)malloc(sizeof(int **));已经有内存空间不用再申请
*p=(int** )malloc(row*sizeof(int *));//二级
printf("test二级:*p:%p\n",*p);
printf("test二级:*p+1:%p\n",*(p+1));
**p=(int* )malloc(col*sizeof(int));//一级
printf("test一级:**(p+1):%p\n",**(p+1));
printf("test一级:**p:%p\n",**p);*/
int i;
*p=(int** )malloc(row*sizeof(int *));//二级
if (NULL == *p)
{
printf("malloc false!\n");
return ;
}
printf("test二级:*p:%p\n",*p);
printf("test二级:*p+1:%p\n",*p+1); //指针的都是4
for(i=0;i<row;i++)
{
*((*p)+i)=(int* )malloc(col*sizeof(int));//一级 ,把*p看成arr好理解 ,**p+i则不行,优先级的问题
//*p[i]=(int* )malloc(col*sizeof(int));//一级
if(NULL==(*p[i]))
{
while(i--)
{
free(*p[i]);
}
free(*p);
}
}
}
int main(void)
{
int** p=NULL;
int arr[2][4];
test(&p,2,4);
int i,j;
int row=2;
int col=4;
printf("arr: ");
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
arr[i][j]=rand()%100;
printf("%d ",arr[i][j]);
}
}
putchar(10);
printf("&arr:%d\n",&arr);
printf("&arr+1:%d\n",&arr+1);
printf("arr:%d\n",arr);
printf("arr+1:%d\n",arr+1);
printf("*arr:%d\n",*arr);
printf("*(arr+1):%d\n",*(arr+1));
printf("arr[0]:%d\n",arr[0]);
printf("arr[1]:%d\n",arr[1]);
printf("arr[0]+1:%d\n",arr[0]+1);
printf("&arr[0][0]:%d\n",&arr[0][0]);
printf("&arr[0][0]+1:%d\n",&arr[0][0]+1);
for(i = 0; i < row; i ++)
{
free(p[i]); //从里往外释放
}
for(i = 0; i < row; i ++)
{
p[i] = arr[i];//将二维数组行地址赋值到对应的一级指针上
}
printf("p: ");
for(i = 0; i < row; i ++)
{
for(j = 0; j < col; j ++)
printf("%d ", p[i][j]); //p[i][j]这里也可以写作*(*(p+i) + j)
}
putchar(10);
printf("p:%d\n",p);
printf("p+1:%d\n",p+1);//指针的都是4
printf("*p:%d\n",*p);
printf("*(p+1):%d\n",*(p+1));
free(p);
return 0;
}
值得注意的一点就是数组是系统自动释放内存的,程序员动态分配的内存则需要自行释放