免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 843 | 回复: 0
打印 上一主题 下一主题

指针问题再探 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-09 14:58 |只看该作者 |倒序浏览
对C的指针的使用总是让人胆战心惊啊,因为看>讲到指针的时候,突然又有一些想法,
但是好像想不明白,于是自己又写了下面的程序实践了一下。
如果我们想动态的分配一个矩阵的长和宽,我们定义了如下的一个矩阵:
int **jj; //jj 是一个指向 int型指针 的 指针。
简单的来看 jj就是一个指针,然后这个指针所指向的内存单元 又是一个指针(p2),
然后p2这个指针了指向了int型的内存单元。
问题就在于指针,内存单元,地址这些概念不好区分,所以使用起来就有麻烦了。
还有就是内存布局的概念在理解指针上也是很重要的,
然后编译器在编译完成后分配虚拟地址也要理解。
现在回到矩阵的问题上来,既然已经分配了jj作为矩阵,那么它的行和列,我们现在其实是不知道的,
我们需要动态的申请内存。
jj作为变量,每一个变量都是分配了一个地址的,也就是jj是一个内存地址的代号。
如何知道jj的地址在哪儿里,使用
&jj
就可以看到jj的地址了,32位机器上为:0x0012ff20
我们通过一个函数来完成这个矩阵的内存申请和初始化,怎么写它的函数接口了。
我们需要另外一个地址来保存jj变量的地址,那我们定义一个指针来指向jj.
int **   *pjj=&jj;   //不能这样定义(int **) *pjj=&jj,这样变成类型conversion了。
当然中间为了容易理解,我加了空格。然后用这个pjj作为函数参数传递进去,就可以分配jj的内存了。
所以函数的声明如下:
void test(int ***a,int row)
另外,多个*号定义的东西成为多级指针,三个*成为3级指针。
然后我们这样传递参数:
test(pjj,10);
则形参a的解释如下:
&a 即为pjj变量的内存地址,*a即为指针变量jj,因为jj还没有被非配内存,
所以它所指向的内存为0xCCCCCCCC,那么& *a则为存放变量jj的内存地址。
程序的输出为:
0x0012ff20:0x0012FEB4  //实际debug 的时候0x0012ff20在内存中显示为:
jj 0x0012ff20     CC  CC   CC   CC
a  0x0012FEB4     20  FF   12   00
下面就是验证理论的代码。
cout    [0]-->【】【】【】【】【】【】【】【】【】【】
   -->[1]-->【】【】【】【】【】【】【】【】【】【】
   -->[2]-->【】【】【】【】【】【】【】【】【】【】
   -->[3]-->【】【】【】【】【】【】【】【】【】【】
   -->[4]-->【】【】【】【】【】【】【】【】【】【】
   -->[5]-->【】【】【】【】【】【】【】【】【】【】
   -->[6]-->【】【】【】【】【】【】【】【】【】【】
   -->[7]-->【】【】【】【】【】【】【】【】【】【】
   -->[8]-->【】【】【】【】【】【】【】【】【】【】
   -->[9]-->【】【】【】【】【】【】【】【】【】【】
怎么初始化该矩阵呢?
i表示行,j表示列,则
*(*(*a+i)+j)=atoi(tmp);//tmp为坐标值, *(*a+i)+j 表示指向的i行j列的内存单元,
要想对这个单元赋值,则需要使用*表示取内存单元的值。
==========================================================
退出矩阵内存申请和初始化函数后,
本例内存地址图:
&pjj (pjj 实际为0x0012ff20)
0x0012FF14  20 FF 12 00 24 FF 12 00
&jj(jj实际为0x00481c80)
0x0012FF20  80 1C 48 00 28 FF 12 00
jj[0]是第一行的首地址(jj[0]实际为0x00481c20)
0x00481C80  20 1C 48 00 C0 1B 48 00
jj[0][0]所在的内存单元为0x00481C20(同为jj[0]的指向的内存地址)  
00481C20  0A 00 00 00 0B 00 00 00   
00481C28  0C 00 00 00 0D 00 00 00   
00481C30  0E 00 00 00 0F 00 00 00   
00481C38  10 00 00 00 11 00 00 00   
00481C40  12 00 00 00 13 00 00 00
下面就是程序源码,注意上面的概念如果用数组下标操作,会容易理解点。
#include "stdafx.h"
#include iostream>
#include "stdio.h"
#include "stdlib.h"
using namespace std;
void test(int ***a,int row)
{
    cout&*a  ":"&a ":" endl;
    *a=new int*[row];
    for (int i=0; irow; i++)
    {
        *(*a+i)=new int [10];
        for(int j =0;jrow;j++)
        {
            char tmp[20];
            memset(tmp,0,sizeof(tmp));
            sprintf(tmp,"%d%d",i+1,j);         
            *(*(*a+i)+j)=atoi(tmp);
            cout  *(*(*a+i)+j)  "   " ;
        }
        cout  endl;
    }   
}
void out()
{
    /*
  char *p,*pp,*pstr="test is go\n";
  int len=0;
  p =pstr;
  while(*p++){len++;pp=p;}
  cout
   int a=9;
   int *p,**jj,*j=0;
   int **pp;
   pp=&p;   
   p=&a;
   cout  &p  ":"    *p ":"  &a":"  &ppendl;
   cout  &jj   ":"    endl;
   int **   *pjj=&jj;
   test(pjj,10);
   for (int i=0; i10 ;i++)
   {
       for (int j =0;j10;j++)
       {
           int *p =jj;
           cout *(p+j)  "   ";
       }
       cout  endl;
   }
   return ;
}
int main(int argc, char* argv[])
{
    out();
    return 0;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/4591/showart_2022546.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP