打印

实际使用中没有问题的话,就**自己认为正确的就可以了

[复制链接]
楼主: wrainp
手机看帖
扫描二维码
随时随地手机跟帖
61
IceAge| | 2008-5-21 20:30 | 只看该作者 回帖奖励 |倒序浏览

我可以理解某些编译器对于&a 的做法

另一个例子是函数指针赋值,我推测compiler设计者对此类问题作过推敲:使用 & 的程序员绝对不会是想对数组首址或函数地址再取地址(因为那没有意义,数组名是被compiler 当作数组首址,一般来说是一个常数),而是想获取数组名或函数名的地址,故而使用 &. 对用户接口设计有经验的人经常会遇到此类问题,你知道用户意图,但是否放宽容错度则很难抉择。
看看visual C, 到了2005,语法严格很多,以前可以编译通过的程序会给出很多错误,以至于我们这里的程序员不愿意升级。我个人认为ms 做得对:被通过的缺陷比没通过要可怕很多,这会直接或间接鼓励犯错。

使用特权

评论回复
62
wxj1952| | 2008-5-21 21:07 | 只看该作者

支持LS。

看看教材是怎样说的:《C与指针》P258

——只有当确实需要时,你才应该使用多层间接访问。不然的话,你的程序将会变得更庞大、更缓慢并且难于维护。


编译器的差别:
...编译器对表达式…,你是不是觉得它有点笨?…是的。这个编译器确实有点旧,它的优化器也不是很聪明。现代的编译器可能会表现的好一点,但也未必。和那些编写差劲的源代码,然后依赖编译器去产生高效的目标代码相比,直接编写良好的源代码显然更好。……

使用特权

评论回复
63
hotpower| | 2008-5-21 21:46 | 只看该作者

00应该不晕~~~早该受此教育了~~~&a+1和a+1是2个"不粘连"的事情~~

computer00 发表于 2008-5-21 10:11 侃单片机 ←返回版面    

62楼: 换了个编译器测试下,更晕,结果发现&a是不允许的…… 

在CodeVisionAVR下,p= (int*)(&a); 提示说非法地址:illegal address。这个就无法验证了。

在CARM编译器下,&a+1跟a+1的值不一样。

在RealView编译器下,&a+1跟a+1的值也不一样。
 
 

使用特权

评论回复
64
computer00| | 2008-5-21 21:49 | 只看该作者

晕~~~我想表达是,&a的值跟a的值相等,就是说&a不是表示a的

&a和a都表示a[]的首地址。

&a+1和a+1,目前只有在keil 51下测试相等,其它测试不相等~~~~有的干脆编译通不过~~~
所以还是别搞&a这样的东西为妙~~~~~~

使用特权

评论回复
65
wxj1952| | 2008-5-21 21:59 | 只看该作者

通不过编译也挺合理的,要不说德国人严谨。

这里有一个比喻:
我在六里桥,想到西客站。这是两条背靠背的公交线,中间没有公交路。但是可以穿胡同走过去,直线距离200米,步行不要5分钟。如果乘坐公交车,就要绕一个大弯,大概2公里。10倍距离!
    穿胡同我不认得路,于是决定打的。上车后跟司机说:“去西客站。”多说了一句废话:“走公交线。”(&a)
这时的出租车司机有3种选择:
1、载上我,穿胡同,不到半分钟,10元钱到手。这就是C51编译器的做法,立即寻址。3种选择里以高效为原则。 (a)
2、拒载。  司机觉得走公交线绕远划不来,2公里也是10元。这就是有些编译器拒绝p=&a;的做法:“你的要求我无法实现。”。“请下车,自己走过去,很近。”(拒绝编译)
3、司机就按我的要求,绕一个大弯到西客站。低效就低效,不赚钱就不赚钱。一切服从客户。这就是正方所希望的编译器优秀而  的功能。“我没让你立即寻址,我让你间接寻址你就间接寻址,别太装聪明了。”
   *(*(&(&

看看教材是怎样说的:《C与指针》P258
——只有当确实需要时,你才应该使用多层间接访问。不然的话,你的程序将会变得更庞大、更缓慢并且难于维护。

间接寻址的最终目的是什么?在这里除了获得数组a某个位置的值 a 外还能有什么?显然,一个数组名a表示&a[0],如果为了访问a的值,一定要通过&&a[0]去达到目的,它是“确实需要”的么?现代编译器会识别出用户的问题,要么拒载,要么自动选择1、直接寻址方式a 帮你取得那个位置的值。就是不可能选择方式3,绕个大圈去取得a的值,结果导致你的程序比别人庞大10倍,甚至无法运行。它不至于那么笨,看不出有优化捷径。
我想现代编译器的工作方式是:即使按方式3操作,最后通过优化器,还是回到了方式1、立即寻址或直接寻址方式。

使用特权

评论回复
66
IceAge| | 2008-5-21 23:19 | 只看该作者

关于多维数组

在c/c++ 中,真正意义上的多维数组是不存在的,多数 compiler 内部还是一维,因为 compiler 知道各维大小,因而可以计算出各个元素的具体偏移。一旦没有了上下文,比如多维数组作为指针变量被传递,compiler 就无法使用多维数组,这也就是很多compiler 对多维数组转换为指针加以限制的原因。
其他一些语言,比如 java, c#, 多维数组有所不同,生成与堆上而不是栈上,可以认为真正意义上的多维数组,比如二维,是必须先生成一个直指针数组,用以存储下一维各个数组的首址。  

使用特权

评论回复
67
HWM| | 2008-5-22 07:48 | 只看该作者

其实C是一种上下跨度很大的语言,因此有人将它称为中级语

在数组的定义中其实已经引入了指针概念,只是为了存储和访问的效率起见未将指针实体化(仅以概念化的常量指针的方式出现)。所以作为常量指针的“数组名”只能出现在表达式中,却不可以作为实体承接数值。

个人认为,C/C++中关于数组的定义过于松散。这不仅表现在其类型定义上,还体现在其组成结构上。正因为数组名被定义为一个常量指针,却又并非指向数组整体,所以使得数组看起来象是一串珍珠,一旦断线就散落一地。

使用特权

评论回复
68
dld2| | 2008-5-22 08:16 | 只看该作者

真难为那些做编译器的

使用特权

评论回复
69
wxj1952| | 2008-5-23 18:28 | 只看该作者

跟汇编语言一致。

汇编程序中经常用到查表方法。一组连续的相同类型数据,表首地址有一个标号TABLE:...数据聚合。     基址 MOV DPTR,#TABLE 加偏移A间接寻址方式被用来获得这个表中一个位置的数据——MOVC A,@A+DPTR。

映像到C是完全一样的!例如:现有数组char  TABLE[10]; C 程序中写下 DPTR=TABLE; 编译后的汇编语句为立即寻址方式:MOV DPTR,#TABLE。C语句ACC=TABLE[2]; 编译为间接寻址 MOVC A,@A+DPTR。

要是想知道汇编程序中TABLE标号的地址在哪里,是不是有点开玩笑?“它可能在哪里?”它除了标识这张表,标识它的内存固定位置之外,它有地址么?汇编语言中TABLE的值怎么可能表示这个表中分立的10个字节的数据?有意义?

使用特权

评论回复
70
渤海三叠浪| | 2009-4-22 00:35 | 只看该作者

对于那些人为定义的东西 只能死记硬背了!!

使用特权

评论回复
71
glf| | 2009-8-27 11:22 | 只看该作者
不知道高手们为什么喜欢用有歧义的东西呢,想让他们输出什么多一条语句不就好了吗?

使用特权

评论回复
72
888WWW| | 2009-9-12 18:34 | 只看该作者
ptr的地址就是指向a[1],所以ptr-1就是a[0]=1

使用特权

评论回复
73
o蓝玉莹| | 2009-9-13 12:27 | 只看该作者
本帖最后由 o蓝玉莹 于 2009-9-13 12:32 编辑

呵呵,大家都说完了吗?本姑娘也来说几句。

1、数组就是数组,函数就是函数,指针就是指针。

2、只有在需要对表达式求值时编译器才会将数组名和函数名转换为指针。

     例如:通常情况下编译器不需要对sizeof、& 的表达式进行求值即可确定操作结果,所以在这里数组名和函数名不会被转换为指针。

3、标准C和传统C对取地址运算符& 的解释不同。

     如果a是某种类型的数组,&a 的类型是该类型数组的指针,而传统C则把&a当成a

4、大家不觉得 computer00 很可爱吗?


     computer00 是偶最喜欢的版主


    上面第2点偶曾求证过GNU的Richard Stallman先生,Richard Stallman先生的回答很幽默,大意是:“当然。如果是你做编译器,你也会这么干!”

使用特权

评论回复
74
mcuisp| | 2009-9-13 12:39 | 只看该作者
哇塞,LS mm来头大。

使用特权

评论回复
75
o蓝玉莹| | 2009-9-13 12:58 | 只看该作者
哇塞,LS mm来头大。
mcuisp 发表于 2009-9-13 12:39


俺可不是大头MM哦
大头很难看滴

使用特权

评论回复
76
mcuisp| | 2009-9-13 14:26 | 只看该作者
知道了,LS是很漂亮的mm
名字就很美。
不知道是见面不如闻名呢?还是闻名不如见面:lol

使用特权

评论回复
77
itelectron| | 2009-9-13 14:30 | 只看该作者
书上的题目了1

使用特权

评论回复
78
o蓝玉莹| | 2009-9-13 14:35 | 只看该作者
知道了,LS是很漂亮的mm
名字就很美。
不知道是见面不如闻名呢?还是闻名不如见面:lol
mcuisp 发表于 2009-9-13 14:26


人如其名也,
闻名如见面。

使用特权

评论回复
79
xuyiyi| | 2009-9-13 15:05 | 只看该作者
个人觉得, 正规的开发人员 ( 而不是玩技术的 ) 应该避开这些缺陷, 对于花哨玩意儿, 简单弱智点好. 完全可以参考 C++ 甚至 Java 的某些风格去写程序, 这些语言的一些规定其实也是在逐步修正 C 的问题.

使用特权

评论回复
80
mcuisp| | 2009-9-13 15:15 | 只看该作者
热烈赞同楼上的说法!!!
对于这种绕脑筋的题,我现在懒得去看了。
实在有需要,用编译器来实验,呵呵。

使用特权

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

本版积分规则