打印

搞到今天都没弄懂的C语言问题...

[复制链接]
楼主: zq1987731
手机看帖
扫描二维码
随时随地手机跟帖
21
machunshui| | 2010-2-26 10:45 | 只看该作者 回帖奖励 |倒序浏览
其中如果
int A[10];  
int (*p)[5];  

无论如何p也不能指向A。

两者元素数目必须相同,
int A[10];  
int (*p)[10];

p = &A;

才可以。

使用特权

评论回复
22
yewuyi| | 2010-2-26 10:47 | 只看该作者
(*(p+1))[0] = 5; // 等价于 A[5] = 5;
---------------------------------------------

这个容易让不熟悉C的看不懂。
P这个指针指向的目标长度是5,即由int (*p)[5]定义时确定其size为5,所以P+1对应的物理地址落在&A[5]上,把(*(p+1))[0] 简化一下看成为(*x)[0],则(*x)[0]的对应物理地址也落在&A[5]上,所以,事实上形成:(*(p+1))[0] = 5; // 等价于 A[5] = 5;

使用特权

评论回复
23
yewuyi| | 2010-2-26 10:52 | 只看该作者
p=A能不能通过,早就已经有大把的人做了各种编译器的测试,呵呵,印象中网络上应该有大把测试例子。

呵呵,自然是推荐大家写成p=&A,至少这样更容易看明白,只是P=A,到底是错是对,并没有明确的定论,大家都争议了多少年了,这是一个C语言未明确的东西,呵呵,这应该也是C的特色,足够灵活,但也足够让人糊涂。

使用特权

评论回复
24
yewuyi| | 2010-2-26 10:53 | 只看该作者
呵呵,一个指针引发的血案。

使用特权

评论回复
25
HWM| | 2010-2-26 10:56 | 只看该作者
呵呵,在此所列例子只是用来说明些问题而已。别过于认真,也不建议如此使用。

严格按规则行事的话,必须将A[]和*p定义成同类型等大小的变量才可以。因此VC中严格要求是:

int A[10];
int (*p)[10];

时,才能使用

    p = &A;

但Keil较为宽松,因此可以混过去。

使用特权

评论回复
26
machunshui| | 2010-2-26 11:16 | 只看该作者
呵呵,

int A[10];
int (*p)[10];

    p = A;

我测试恰恰是keil,vc,IAR通不过。


picc却能通过。

p = &A,
各种编译器总是没有问题。

使用特权

评论回复
27
冷漠| | 2010-2-26 11:48 | 只看该作者
本帖最后由 冷漠 于 2010-2-26 13:31 编辑
int A[10];  // 实际分配一个含10个int单元的数组
int (*p)[10];  // 定义一个指针,注意尚未有实际空间被指定


同意上面差别。那么下面概念/写法一定是对的:[ ]左傍指针——[ ]左边必是指针,所以:
         *P是指针,P[ ]是指针,A是指针,(*P)也是指针。所以:
          *P=A ;——>   P=&A; /  P=A;  // 概念上一样。既然编译结果唯一,自然2种写法都可以。

使用特权

评论回复
28
cwei85| | 2010-2-26 12:42 | 只看该作者
感觉和函数指针类似

使用特权

评论回复
29
Mindor| | 2010-2-26 14:02 | 只看该作者
有意思~~

使用特权

评论回复
30
zq1987731|  楼主 | 2010-2-26 14:15 | 只看该作者
本帖最后由 zq1987731 于 2010-2-26 14:18 编辑

谢谢大家的热心帮助!!
最近本人主要在搞一些钻牛角尖问题...主要因为有些前辈的程序实在太注重技巧,自己没点技巧就没法见招拆招~~
比如...有人偏偏就喜欢用下面这种语句:
(*(void(*)(void))0)();
还有的人风格是不错,就是...一个变量union套struct套来套去,1~6层这也没什么,10几层...这就有点什么了,比如A.B.C.D.E.F.G.H.I.J = 0;(把前面字母换成名字超长的类型)一个变量上百个字符,这真是非常雷人啊...
这个指针问题我基本弄懂怎么回事了...现在试着用自己的语言组织一下..
    比如有这么个数组定义:
    int a[10];
    int *p;
    p = a;
    这个就是最常用的类型,随后*p便代表a[0],也可写成p[0],然后一旦执行了p++;之后,*p就代表a[1],p[1]等效为*(p+1)指的就是a[2]
    如果扩展成二维数组,又假设有如下定义:
    int b[10][10];
    那么本质上是由10个一维数组组成,这10个数组的首地址为b[0]~b[9],这里的b代表的就是b[0]这个【首地址】的【地址】,现在有如下定义
    int (*p)[10];
    那么只要如此赋值:
    p = &b[0];  或者p = b;
    那么(*(p + 1))[5];代表的就是b[1][5],这时候用p[1][5]来描述也是一回事..
    又是同理,再次假设一个定义:
    int c[10][10][10];
    int (*p)[10][10];
    int (*q)[10];
    int *r;
    如此赋值:p = &c[0];  或者p = c;
    那么(*(p + 5))[2][6]和c[5][2][6]等效
    继续:q = &c[0][0];   或者q = c[0];
    那么(*(q + 12))[3]和c[1][2][3]等效
    再来:r = &c[0][0][0];  或者r = c[0][0];
    那么*(r + 789)和c[7][8][9]等效......
    这样的理解应该没问题了把?

使用特权

评论回复
31
Mindor| | 2010-2-26 14:33 | 只看该作者
指针数组:即一个由若干指针构成的数组。
    例:int *p[10]   //定义了一个数组,该数组的元素为指向整型数据指针p。

数组指针:即一个指向数组的指针。
    例:int (*p)[10]   //定义了一个指针,该指针指向一个由十个元素组成的数组。

使用特权

评论回复
32
machunshui| | 2010-2-26 15:06 | 只看该作者
我的keil通不过,有error恶

err.JPG (130.23 KB )

err.JPG

使用特权

评论回复
33
冷漠| | 2010-2-26 16:41 | 只看该作者
我keil C51 编译通过.

使用特权

评论回复
34
xlsbz| | 2010-2-26 17:17 | 只看该作者
[]这个符号就是人强行规定的。 比较难以理解。只能死记硬背。

*这个符号是客观存在的。

API--------------控件   等价于    *-----------[]


个人观点

使用特权

评论回复
35
mohanwei| | 2010-2-26 17:33 | 只看该作者
struct搞个十几层很正常,编过复杂点的程序你就知道必要性了,不过人家不会A.B.C.D.E.F……这么用,
肯定函数也是一个套一个的,一层函数对应一层struct,数据则通过指针传递

使用特权

评论回复
36
sinanjj| | 2010-2-26 17:50 | 只看该作者
我一会用gcc试试.

各位前辈有讲讲为啥 p=A和p=&A一样啊. 这个真不知道. A作为一个地址, 也应该存在内存的, 有实体的, &A应该就是存放这个地址的内存地址啊. A==&A这个是咋回事? 难道指针变脸都在内存无实体???????



还有LS的"struct搞个十几层" 这个也太夸张了吧.........超大型数据库上这个量还有可能.

使用特权

评论回复
37
冷漠| | 2010-2-26 20:21 | 只看该作者
个人看法:最重要的一点:A是常量指针!它的地址是一个常数。一个常数是包含在程序里的吧?例如:MOV A,#55H; 这个55H是跟着语句跑的吧,它有地址特征吗?它需要间接寻址吗?

使用特权

评论回复
38
xjycug| | 2010-2-26 21:55 | 只看该作者
int *p[10];
和int (*p)[10]
定义不同。
最大的区别应该是在做指针的加法时就很明显吧。即p++;
如果是 int *p[10]; 则p++,p会增加2
如果是 int (*p)[10],则p++,p会增加20;
呵呵,我觉得应该是这样吧。主要是告诉编译器指针的类型。

使用特权

评论回复
39
hizog| | 2010-2-26 23:35 | 只看该作者
本帖最后由 hizog 于 2010-2-26 23:46 编辑

这么热闹啊!我前段时间也用了这个数组,不玩虚的,直接举例。
unsigned char  u8_sample1[3]={1,2,3};
unsigned char u8_sample2[3]={3,2,1};
unsigned char *p_u8_sampleX[2]={u8_sample1,u8_sample2};
于是
*p_u8_sampleX[0] = u8_sample1[0];


unsigned char u8_sampleXY[2][3]={{1,2,3}{3,2,1}};
unsigned char  (*p)[3] = u8_sampleXY;
*p_u8_sampleXY[0]  = u8_sampleXY[0][0]=1;
*(p_u8_sampleXY+1)[2]  = u8_sampleXY[1][2]=1;
*(*(p_u8_sampleXY+1)+1)  = u8_sampleXY[1][1]=2;

使用特权

评论回复
40
冷漠| | 2010-2-27 11:30 | 只看该作者
*p_u8_sampleXY[0]  = u8_sampleXY[0][0]=1;
*(p_u8_sampleXY+1)[2]  = u8_sampleXY[1][2]=1;
*(*(p_u8_sampleXY+1)+1)  = u8_sampleXY[1][1]=2;



写清楚呀:
*u8_sampleXY[0]  = u8_sampleXY[0][0]=1;
*(u8_sampleXY+1)[2]  = u8_sampleXY[1][2]=1;
*(*(u8_sampleXY+1)+1)  = u8_sampleXY[1][1]=2;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则