在JM8.6中多次出现多级指针,之前的博文已经有介绍多级指针和多级数组的关系. 下面继续来看看多级指针, 以便进一步熟悉.(说明:下面的程序都没有考虑堆内存的释放)
先来简单预热一下:
#include <stdio.h>
typedef unsigned char byte;
int main()
{
byte a = 0;
printf("%d\n", a);
byte *p = &a;
*p = 100;
printf("%d\n", a);
return 0;
}
#include <stdio.h>
typedef unsigned char byte;
void setData(byte *p)
{
*p = 100;
}
int main()
{
byte a = 0;
printf("%d\n", a);
setData(&a);
printf("%d\n", a);
return 0;
}
#include <stdio.h>
#include <malloc.h>
typedef unsigned char byte;
byte* getMemory()
{
byte *p = (byte *)calloc(1, sizeof(byte));
return p; // 返回指向堆空间的栈指针
// 如果返回指向栈空间的栈指针,则没用
}
int main()
{
byte *p = NULL;
p = getMemory();
*p = 100;
printf("%d\n", *p);
return 0;
}
#include <stdio.h>
#include <malloc.h>
typedef unsigned char byte;
void getMemory(byte* &p)// 在C++中可以用引用
{
p = (byte *)calloc(1, sizeof(byte));
}
int main()
{
byte *p = NULL;
getMemory(p);
*p = 100;
printf("%d\n", *p);
return 0;
}
// 下面这个程序有错误
#include <stdio.h>
#include <malloc.h>
typedef unsigned char byte;
// 该函数不能实现相应的功能
void getMemory(byte *p)
{
p = (byte *)calloc(1, sizeof(byte));
}
int main()
{
byte *p = NULL;
getMemory(p);
*p = 100;
printf("%d\n", *p);
return 0;
}
上面这个有错误的程序应该改为:
#include <stdio.h>
#include <malloc.h>
typedef unsigned char byte;
void getMemory(byte **p)
{
*p = (byte *)calloc(1, sizeof(byte));
}
int main()
{
byte *p = NULL;
getMemory(&p);
*p = 100;
printf("%d\n", *p);
return 0;
}
上面预热之后,对指针的概念算是基本懂了 . 由此可以得出这样的结论:如果要修改主调函数中的整形变量a, 那么在被调函数中就要用指向整形变量的指针来指向a;如果要修改主调函数中的整形指针变量p,那么在被调函数中,就应该用指向整形指针的指针来指向p.
下面看一下稍微复杂的情况:
#include <stdio.h>
#include <malloc.h>
typedef unsigned char byte;
void getMemory(byte **p, int n)
{
*p = (byte*)calloc(n, sizeof(byte));
}
int main()
{
int n = 3;
byte *p = NULL; // 一维指针
getMemory(&p, n);
int i;
for(i = 0; i < n; i++)
{
p[i] = i + 1; // 在形式上是一维数组
}
for(i = 0; i < n; i++)
{
printf("%d\t", p[i]);
}
printf("\n");
return 0;
}
结果为:
1 2 3
下面看看二维数组的动态分配:
// 搞懂这个程序. 真的很重要.
#include <stdio.h>
#include <malloc.h>
typedef unsigned char byte;
/*
下面假设:rows为3, columns为4.
被调函数中的*array2D实际上就是指向指针的指针,
*array2D实际上就指向了3段连续的内存.
(*array2D) + 0 指向了第1段连续的内存;
(*array2D) + 1 指向了第2段连续的内存;
(*array2D) + 2 指向了第3段连续的内存;
每一段连续的内存相当于一个byte* 形式的指针.
get_mem2D中第二行申请的空间大小为:3 * 4
地址是连续的,本质上是连续的存储单元,
可以把每一段内存理解为矩阵的一行, 如此一来,便有:
(*array2D)[0]指向了矩阵的第1行;
(*array2D)[1]指向了矩阵的第2行;
(*array2D)[2]指向了矩阵的第3行;
而每一行又有4个byte型的元素.
注意:被掉函数中的*array2D实际上就是主调函数中的array2D
*/
void get_mem2D(byte ***array2D, int rows, int columns)
{
*array2D = (byte**)calloc(rows, sizeof(byte*));
(*array2D)[0] = (byte*)calloc(columns * rows, sizeof(byte));
int i;
for(i = 1; i < rows; i++)
(*array2D)[i] = (*array2D)[i - 1] + columns ;
}
int main()
{
int rows = 3;
int columns = 4;
byte **array2D = NULL;
get_mem2D(&array2D, rows, columns);
int i, j;
for(i = 0; i < rows; i++)
{
for(j = 0; j < columns; j++)
{
array2D[i][j] = i * columns + j + 1;
}
}
for(i = 0; i < rows; i++)
{
for(j = 0; j < columns; j++)
{
printf("%d\t", array2D[i][j]);
}
printf("\n");
}
return 0;
}
结果为:
1 2 3 4
5 6 7 8
9 10 11 12
下面看看三维数组的动态分配:
#include <stdio.h>
#include <malloc.h>
typedef unsigned char byte;
void get_mem2D(byte ***array2D, int rows, int columns)
{
*array2D = (byte**)calloc(rows, sizeof(byte*));
(*array2D)[0] = (byte*)calloc(columns * rows, sizeof(byte));
int i;
for(i = 1; i < rows; i++)
{
(*array2D)[i] = (*array2D)[i - 1] + columns ;
}
}
void get_mem3D(byte ****array3D, int frames, int rows, int columns)
{
*array3D = (byte***)calloc(frames,sizeof(byte**));
int j;
for(j = 0; j < frames; j++)
{
get_mem2D( (*array3D)+j, rows, columns );
}
}
int main()
{
int rows = 3;
int columns = 4;
int frames = 10;
byte ***array3D = NULL;
get_mem3D(&array3D, frames, rows, columns);
int i, j, k;
for(i = 0; i < frames; i++)
{
for(j = 0; j < rows; j++)
{
for(k = 0; k < columns; k++)
{
array3D[i][j][k] = (j + 1) * 10 + k + 1;
}
}
}
for(i = 0; i < frames; i++)
{
printf("Frame number is %d\n", i + 1);
for(j = 0; j < rows; j++)
{
for(k = 0; k < columns; k++)
{
printf("%d\t", array3D[i][j][k]);
}
printf("\n");
}
printf("\n\n");
}
return 0;
}
结果为:
Frame number is 1
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 2
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 3
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 4
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 5
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 6
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 7
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 8
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 9
11 12 13 14
21 22 23 24
31 32 33 34
Frame number is 10
11 12 13 14
21 22 23 24
31 32 33 34
至此,总算搞清楚了多数指针和多维数组的关系.