现在的位置: 首页 > 综合 > 正文

数组指针, 指针的指针

2013年05月25日 ⁄ 综合 ⁄ 共 4779字 ⁄ 字号 评论关闭

指向数组的指针:

很多人以为“指向数组的指针”就是“指向指针的指针”,于是有人写这样的代码:
int a[3][4];
int **p = a;//错误
  这个代码的错误之处在于a是一个数组,它的成员也是数组,所以a叫做“数组的数组”——C++中严格说来没有二维数组。那么,你要用一个指针来记录a,就要用一个能表示“数组的数组”的指针,以下代码是正确的:
int (*p)[4] = a;//正确
  只有这样才能保证++p使p指向a的下一对像(该对像是一个数组)。
  顺便提一句:不要写成“int *p[4];”

指针本身就是一个变量,当指向数组时,也有类型:
如:

int     c[3][4][5];

c,&c,&(&c),c[0]所指都是数组首地址,可是类型不同。
                    
&c的类型是(int(*)[3][4][5]) 
&c+1指的是:&c+sizeof(int)*3*4*5

c的类型是(int(*)[4][5]),

c+1指的是:c+sizeof(int)*4*5
 
*c,即c[0],   类型是int(*)[5]  
*c+1 指的是:c+sizeof(int)*5
  
*c[0]类型是int*   

*c[0]+1指的是:c+sizeof(int)+1

 

数组做为形参时,退化为指针

三维数组,退化为指向二维数组的指针
二维数组,退化为指向一维数组的指针
一维数组,退化为指向类型(如int)的指针


#include<stdio.h>
void main()
{
void average(float *p,int n);          //求平均分数,形参为指向变量的指针变量
void search(float(*p)[4],int n);       //求第n个学生的成绩,形参为一指向4维数组的指针变量
float score[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};
average(*score,12);                    //传入实参*score与&score[0][0]即指向的是元素
search(score,2);                       //传入实参score其指向为数组中的一行。
}
void average(float *p,int n)
{
float*p_end;
float sum=0,aver;
p_end=p+n-1;
for(;p<=p_end;p++)                     //p指向下一个元素
   sum+=*p;
aver=sum/n;
printf("average=%5.2f/n",aver);
}
void search(float (*p)[4],int n)          
{
int i;
printf("the score of No.%d are:/n",n);
for(i=0;i<4;i++)                           
   printf(" %5.2f",*(*(p+n)+i));
printf("/n");
}

 

 

指向数组的指针的解引用

三维数组,可以看做是指向二维数组的指针,解引用后为指向一维数组的指针,即二维数组
二维数组,可以看做是指向一维数组的指针,解引用后为指向类型(如int)的指针,即一维数组
一维数组,可以看做是指向类型(如int)的指针,解引用后为类型数(如int数),即一个数

int main(int argc, char* argv[])
{

    int a[5= {1,2,3,4,5};
    
int b[3][4= { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}};

    printf("%p/n",&a);      
    printf(
"%p/n",&a+1);    
    printf(
"/n");
    printf(
"%p/n",a);        
    printf(
"%p/n",a+1);      

    printf("/n");
    printf(
"%p/n",&b);       
    printf(
"%p/n",&b+1);     
    printf(
"/n");
    printf(
"%p/n",b);        
    printf(
"%p/n",b+1);      
    printf(
"/n");
    printf(
"%p/n",*b);       
    printf(
"%p/n",*b+1);     
    printf(
"/n");
    printf(
"%p/n",**b);       
    printf(
"%p/n",**b+1);     
    getch();
    
return 0;
}

 

有人问我二三维指针的事,讲了一大堆,总结了以下代码:

void TestPointer()
{
        // 优先级:()>[]>*

        int i,j,k;
        // 指针和数组
        // 看是指针还是数组要看他的名字(不带[]也不带*)能否直接对其进行内存分配
        // 因为数组是确定的分配好内存地址的,而指针则是用于指向地址的
        // 所以为指针分配内存或赋值时,应该理解为指向数组地址或其他地址

        // 读法:由低优先级向高优先级读
        // *Array0[10]:指针——数组
        // int **Array1[2]:指针——指针——数组(二维指针数组)
        // *(*pPointer4)[2]:指针——数组——指针(指向指针数组的指针)
        // (*pPointer3)[30][20]:数组——数组——指针(指向二维数组的指针)

        // 1、数组和指针数组
        int Array[10];    // Array是数组,有10个元素,元素的类型是int型
        int *Array0[10];    // Array0是指针数组,有10个元素,元素的类型是int型指针
        for( i=0; i<10; i++ )
        {
                Array0 = new int[i+1];    // Array0是int型的指针
                delete[] Array0;
        }
        int **Array1[2];    // 一个指向指针的指针的数组(二维指针数组),拥有两个元素
        // 每一个元素都是int ** 型(指向指针的指针) ,但 Array1 终究也是个数组,
        Array1[0]=new int *[10];    // int *[10]为指针数组,见下面一条
        Array1[1]=new int *[10];
        delete [] Array1[0];
        delete [] Array1[1];

        // 2、指向数组的指针
        int *pPointer0=new int[10];    // pPointer0是指针,赋值号右边但申请的是一个数组,只不过用指针指向它

        // 指向“指针数组”的“指向指针的指针”
        // 定义一个数组,有10个元素,元素的类型是int*
        // 用指向指针的指针指向该指针数组, pPointer1[]表示数组中的每个元素(int *)
        // 为指针数组中每个元素申请空间,并为申请到的空间中的元素赋值
        int **pPointer1=new int*[10];
        for( i=0; i<10; i++ )
        {
                // *(pPointer1+i) = new int[i+1]; 也可
                pPointer1 = new int[i+1];
                for( j=0; j<i+1; j++ )
                {
                        // *(*(pPointer1+i)+j) = 1;
                        pPointer1[j] = 1;
                }
                delete[] pPointer1;
        }
        delete [] pPointer1;

        // 指向二维数组的指针,
        // 该二维数组最低维数的元素数量为8个,类型为int
        int (*pPointer2)[8];
        // 理解 (*pPointer2)[8]:
        // (*pPointer2)说明它是一个指针,
        // (*pPointer2)[8]说明p2一次跳过8个元素,
        //         即pPointer2指向一个二维数组,且最低维为8,该数组元素不是指针
        pPointer2= new int[10][8];
        for( i=0; i<10; i++ )
        {
                for( j=0; j<8; j++ )
                {
                        pPointer2[j] = 20;
                }
        }
        delete []pPointer2; // 删除(释放)二维数组

        // 指向三维数组的指针,该三维数组低两维的元素数量为[30],[20],类型为int
        int (*pPointer3)[30][20];    // 这个数组低两维必须是确定的
        pPointer3=new int[1][30][20];
        delete []pPointer3; //删除(释放)三维数组

        // 指向二维指针数组的指针
        // 声明一个3*2的二维数组,元素是指针,
        // 用一个指针的指针pPointer4指向该数组首地址
        // pPointer4[j]是该二维数组的每个元素,(i<=3 j<=2)
        int *(*pPointer4)[2] = new int *[3][2];
        // 对*(*pPointer4)[2]的理解:
        // (*pPointer4)说明pPointer4是指针,
        // (*pPointer4)[2]说明这个指针写成pPointer4时,一次跳两个元素,即pPointer4指向的数组最低维=2
        // *(*pPointer4)[2]说明每个元素都是指针
        for( i=0; i<3; i++ )
        {
                for( j=0; j<2; j++ )
                {
                        pPointer4[j] = new int [5];
                        for( k=0; k<5; k++ )
                        {
                                pPointer4[j][k] = 5;
                        }
                        delete[] pPointer4[j];
                }
        }
        delete[] pPointer4;
}

抱歉!评论已关闭.