定义(*p)[4]和p[][4](会产生错误)的区别
来源:互联网 发布:天刀神刀捏脸数据男 编辑:程序博客网 时间:2024/04/29 05:08
在百度知道里偶然看到一个问题,提问者的提问内容如下:
#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));
}
}
- 定义(*p)[4]和p[][4](会产生错误)的区别
- P,*P和&P的区别
- *p++和*++p的区别
- *p++和*++p的区别
- *p和p[]的区别
- *p++和*++p的区别
- *p++和*++p的区别
- *p++和*++p的区别
- *p++和*++p的区别
- *p++和*++p的区别
- *p++和*++p的区别
- *p++和*++p的区别
- *p和**p的区别
- *p,p和&p区别:
- p,&p,*p的区别
- p,&p,*p的区别
- p &p *p的区别
- p,&p,*p的区别
- 3_2
- 对象的可见性和作用域
- java获得当前时间(转载)
- 取消事件处理
- 气泡事件
- 定义(*p)[4]和p[][4](会产生错误)的区别
- 原码、反码、补码最初是针对负数设计的
- 不管到哪都是为了赚钱
- 在香港可以不受国内法律约束,钻了法律的空子,要是真NB。。。就关闭中文搜索服务..
- Google 只是去了HK而已。。。。
- google走了,微虎来了
- 遇到你是最美丽的意外
- 中国要挺住
- 数据库面试笔试题集(转)