C/C++中的二维指针问题--转载

转载:http://blog.csdn.net/deadknightliu/archive/2009/06/03/4238717.aspx

原作者:DeadKnightLiu

感谢原作者!


指针是可变数组的首地址。正因为是可变数组,所以一般使用指针时都是采用动态内存分配和释放的方式。一维指针形式简单,容易理解。平时应用较多。二维数组和二维指针比较复杂,并且在动态内存分配与释放方面比较复杂且难以理解。但是二维数组和二维指针是非常有用的。

     考虑以下应用:对一幅图像进行模板运算。这必然会牵涉到对图像的各象素点的操作。此时使用一维指针进行图像传递时,不可避免的会使用形如*(p+i*width+j)的方式完成对图像象素点的访问。这种方式很不直观并且编写程序时容易出错。如果使用二维指针进行图像数据的传递,则会收到很好的效果。可以采用p[i][j]的方式直接操作象素点,直观又便于维护。因此掌握二维数组和二维指针是必要的。

使用http://www.wangchao.net.cn/bbsdetail_59038.html中的示例。

定义如下3个二维数组和二维指针进行说明:

1.         int** ptr;

2.         int *ptr[M];

3.         int (*ptr)[M];

以上都是存放整数的二维数组,并且都可以通过ptr[i][j]的形式访问内容。但是它们之间有很大的差别。以下依照文中提到的方面进行分析。

l         内容
三个ptr本身都是指针,并且是二维指针,但是它们的最终内容总是整数。但中间内容,形如ptr[i]并不是整数,而是指针int *.

l         意义
1. int** ptr 表示指向(一组指向整数数据指针)的指针;
2. int *ptr[M] 是指针数组,表示指向(M个指向整数指针)的指针;
3. int (*ptr)[M]表示指向一组(指向包含M个整型数据的指针)的指针。

l         所占空间
1和3占用一个内存空间,在32位平台上为4个字节,也就是一个指针。
2是M个指针,在其定义过程中编译器即对其进行了分配,占用4*M共4M个字节。

l         用法
1. int** ptr 表示指向(一组指向整数数据指针)的指针,是一个二维指针。在其定义过程中,编译器并不对其进行内存的分配,因此必须自己管理其内存的分配与释放。典型使用如下:

int** ptr;

int i,j;

ptr = (int**)malloc((sizeof(int*))*M); 

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<M;i++)

{

       ptr[i] = (int*)malloc(sizeof(int)*N); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为M*N的二维数组首地址

//可以访问ptr[0:M-1][0:N-1]的数据

//操作

for (i=0;i<M;i++)

{

         free(ptr[i]); 

}

free(ptr);

使用上述方法分配内存,最终ptr耗费的内存空间为M*sizeof(int*)+M*N*sizeof(int)

2. int *ptr[M] 是指针数组,表示指向(M个指向整数指针)的指针。是一个二维指针。但是在定义的时候,编译器已经为ptr指向的M个指向整数的指针ptr[0:M-1]分配了内存。也就是说,定义之后即可得到ptr的地址以及用于存放ptr[0:M-1]的内存空间4MB。要使用ptr必须对ptr[i]分配内存。分配内存后,ptr地址相应内存空间填入ptr[i]指向内存地址。使用如下操作:

int* ptr[M]; 

int i,j; 

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<M;i++)

{

         ptr[i] = (int*)malloc(sizeof(int)*M); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为M*N的二维数组首地址

//可以访问ptr[0:M-1][0:N-1]的数据

//操作

for (i=0;i<M;i++)

{

         free(ptr[i]); 

}

//free(ptr); //此处不释放ptr内存,是因为ptr的内存是由编译器分配的。

使用上述方法分配内存,最终ptr耗费的内存空间为M*sizeof(int*)+M*N*sizeof(int),其中M*sizeof(int*)为编译器分配,M*N*sizeof(int)为程序员自己分配。

3. int (*ptr)[M]表示指向一组(指向包含M个整型数据的指针)的指针。该定义限定了ptr[i][0:M-1],所有指针ptr[i]必须指向长度为M的数组。使用方式如下:

int (*ptr)[M]; 

int i,j; 

 

printf("The Address of ptr:%10x\n",ptr); 

ptr = (int (*)[M])malloc(sizeof(int)*M*N); //一次分配连续内存

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<N;i++)

{

//      ptr[i] = (int [M])malloc(sizeof(int)*M); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为N*M的二维数组首地址

//可以访问ptr[0:N-1][0:M-1]的数据

//操作

free(ptr);

使用上述方法分配内存后,ptr所占内存空间为M*N*sizeof(int)(不考虑不同操作系统用于管理的内存)。ptr内存空间中保存的为最终内容而非ptr[i]地址。



C/C++中的二维指针问题--转载 - 大灰狼 - 大灰狼 的博客?

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值