从JM8.6解码器中学习多级指针的应用

        在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


       至此,总算搞清楚了多数指针和多维数组的关系.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值