定义(*p)[4]和p[][4](会产生错误)的区别

来源:互联网 发布:天刀神刀捏脸数据男 编辑:程序博客网 时间:2024/04/29 05:08
对C语言中一个数组指针及指针数组问题的分析
2009年02月07日 星期六 下午 11:49

在百度知道里偶然看到一个问题,提问者的提问内容如下:

#include "stdio.h"
#define M 3
#define N 4
main()
{
int a[M][N],*p[M],j,k;
for(j=0;j<M;j++)
p[j]=a[j];

for(j=0;j<M;j++)
for(k=0;k<N;k++)
scanf("%d",&p[j][k]);

for(j=0;j<M;j++)
{
for(k=0;k<N;k++)
printf("%5d",p[j][k]);
}
}
上面程序没有问题,但是在定义方面,教材上说a[j]是常量,而p[j]为变量,我认为这两者皆为指针变量(一级),(就因为上面的第一个for语句).不知我错了,还是教材错了,请各位指教
========================================================================================================================
还有,在定义"行指针"的时候,例如:
int a[3][4],(*p)[4];
我认为(*p)[4]等价于p[][4];
可在以"后者"调用的时候出现语法错误;

 

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
对此问题做一个简要分析,如下:
     首先明确一点,即如果定义了 int (*p)[4];就压根没有p[][4]这一说,定义了以后p代表内存空间仅仅可以存放一个指针值,并且这个指针值只能是一个长度为4的整形数组的首地址,所以p[][4]这个形式是错误的,同理int *p[4]则是一个指针数组,可以存放四个整形变量的地址.
     在c语言中,数组名,以及**数组的数组名+第一个维数,分别表示数组首地址和第几行元素所占空间的首地址,和指针并不是同一种类型数据,指针可以指向任何一个存放定义数据类型的空间地址,即其值是可变的,而以数组名命名的变量代表系统预先编址空间的地址,对它赋值意味着强制为变量代表的空间强制重新编址,系统是不允许地,只允许以下标访问元素方式对空间中存储的数据变量进行赋值操作.
     在这段程序里,*(a+j)和a[j]是等效的,都代表第j行元素所占空间首地址.而int *p[M]和int (*p)[4]是不一样的,前者是一个指针数组,这个数组可放M个指针元素,后一个是数组指针,它只能指向一个有四个元素的数组,但是并没有p[][4]这种说法,因为(*p)[4]只是一个单独的变量,它指向的空间只能存储一个值,就是一个有长度为4的一维数组首地址或一个二维数组某一行数中据所占空间首地址.
     就是说,假如这样定义,int a[3][4],(*p)[4],那么可以这样使用
for ( int i = 0; i < 3; )
{
     //p是一个数组指针变量而不是数组变量,不能用p[]或p[][]这种形式
     p = a[i++];
     for ( int j = 0; j < 4; )
         printf( *(*(p+0)+j++) );//scanf("d%",&*(*(p+0)+j++));
}
     或者
//p是一个数组指针变量而不是数组变量,不能用p[]或p[][]这种形式
p = a;
for ( int i = 0; i < 3; )
{
     for ( int j = 0; j < 4; )
     printf( *(*(p+i++)+j++) );//scanf("d%",*(*(p+i++)+j++) );
}

同理,
int a[M][N],*p[M],j,k;
for(j=0;j<M;j++)
     p[j]=a[j];//或者p[j]=&a[j][N个中的某一个值]
这种情况下,数组p(不是指针p)里面放了M个地址,它们是数组a的M行数据所占空间的首地址或者每行数组第一个元素的地址.用这个值的时候就应该这样用
for(j=0;j<M;j++)
{
     for(k=0;k<N;k++)
     {
          //p是一组数组变量,只能以p[x]或*(p+x)这两种形式使用
          scanf("%d",&*(p[j]+k));
          //scanf("%d",&*(*(p+j)+k));
     }
}

for(j=0;j<M;j++)
{
     for(k=0;k<N;k++)
     {
          //同理,输出时也只能以p[x]或*(p+x)这两种形式使用
          printf("%5d",*(p[j]+k));
          printf("%5d",*(*(p+j)+k));
     }
}

原创粉丝点击