打印

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

[复制链接]
14426|87
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wrainp|  楼主 | 2008-5-14 18:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
computer00| | 2008-5-14 20:48 | 只看该作者

*(a+1)即a[1],就是2。*(ptr-1)就是a[0],即1。

使用特权

评论回复
板凳
赤铸| | 2008-5-14 23:19 | 只看该作者

ptr 是个陷阱, *(ptr-1)=5

&a+1 指向整个数组 a 的下一个
ptr-1 指向数组尾
*(ptr-1)=5

使用特权

评论回复
地板
simon21ic| | 2008-5-15 01:04 | 只看该作者

大家都稀饭玩这个啊?

知其然,还要知其所以然

关键:&a+1是什么意思
&a是取a的地址,结果是指向a的类型的指针,对指针的+1是指针+指针指向的类型的长度
a的类型是int [5],那么&a的操作的结果是得到一个指向int [5]类型的指针,那么这个类型长度是sizeof(int) * 5,&a+1其实得到的是a的地址+sizeof(int)*5

使用特权

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

看来不同的编译器处理结果不一样。

我在keil下编译,&a+1的结果就是a+1。要不要那个&都无所谓。

使用特权

评论回复
6
simon21ic| | 2008-5-15 11:36 | 只看该作者

8位嵌入式编译器很多都不完全按照标准的

这个很正常,我用VC++测试确实就是按照标准所说的一样
没用过Keil,这个其实也可以说是Keil的Bug了吧,这个地方没有必要和标准不一致,因为不影响性能也没有处理器的限制

使用特权

评论回复
7
liudewei| | 2008-5-15 13:57 | 只看该作者

应该是相同的

使用特权

评论回复
8
fishxia| | 2008-5-15 17:15 | 只看该作者

学习了

使用特权

评论回复
9
HWM| | 2008-5-15 18:36 | 只看该作者

再看一个玩意儿

#include "stdafx.h"

char cA[10];
char cB[10];

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

    *(&cB) = *(&cA); // error, why?
    *(cB) = *(cA); // ok
    *(&cB[0]) = *(&cA[0]); // ok

    return 0;
}

使用特权

评论回复
10
simon21ic| | 2008-5-15 20:36 | 只看该作者

原来在9楼的回复中打了一大堆

其中就涉及到LS说的问题,但由于加入了一些非标准的自己的看法,估计容易成为靶子,就没有发出,而且,意义并不大。

我已经一年多没有工作了,按照报纸上的说法,虽然不是无业游民,也算是无业人员了,所以还望大家不要和我计较

我认为的答案是这样的:数组中的一个可以作为左值,但整个数组不行(要实现数组的整体拷贝的话,可以把数组定义在结构中)
*(cB) = *(cA);//cB和cA其实已经退化为char *了,但&运算作用在数组变量上是并不会引起退化

说实话,我也很想知道为什么这里要限制左值。
数组和结构在内存中都是一小块区域,可以通过指向结构的指针对整个结构进行拷贝(就那LS的例子,如果cA和cB定义为结构的话,结果会怎样?即使这个结构中也一样只定义一个长度为10的char数组)。那么为什么不可以通过指向整个数组的指针来对这个数组执行整体拷贝?
可能到了可以用typedef定义一个指向char[10]的指针类型的时候,也就可以使用整个数组的整体拷贝了
C99的标准中就没有其他的地方可以思考一下吗?

使用特权

评论回复
11
HWM| | 2008-5-15 22:23 | 只看该作者

to 12楼:这恰是数组的诡异之处。

从下面的定义可以看出什么呢?

char cA[10];

一个常量指针cA,和一组连续变量(可以是标量,结构或对象)。再看这个常量指针cA,其所指对象的类型和变量相同,但其自身却还具有一个特殊的“类型”——数组本身。所以有下列式子:

   sizeof( cA ) / sizeof( cA[0] ) = N

其中N为数组长度。

回过头来看&cA,一个“指向cA的指针”,貌似存在其实非也。所以用它可以放在表达式内(如&cA+1),但却不可能对其所指的对象赋值,因为此对象恰是常量指针cA。

使用特权

评论回复
12
simon21ic| | 2008-5-15 23:49 | 只看该作者

原来在9楼准备的答复中

cA的实际类型应该是char [10],也就是一个长度为10的char数组,但实际使用中,往往会退化为指向一个char类型的指针,但幸运的是&和sizeof操作中都不会退化。这里不会退化的意思就是,cA就是你说的那个特殊的类型(sizeof的实际操作我认为是得到参数的类型,计算长度),我不打引号是因为我认为这个类型没有必要特殊,12楼也是这个意思
常量指针确实不可以赋值,但常量指针指向的数据应该可以赋值,所以如果我自己做一个编译器的话,*(&cB) = *(&cA);将没有错误,操作是赋值cA数组给cB数组(cA和cB必须是同样的类型,并且使用了&,就不会退化为char*)

诶,这些讨论就和以前有人提出的a++ = 8;一样没有意义,标准不会也没有必要受到任何影响

使用特权

评论回复
13
赤铸| | 2008-5-16 01:21 | 只看该作者

这种问题其实真不必追究

说的重一点, 有点孔乙己倾向
既然LZ问了, 大家讨论一下知道有这种事也就完了

个人觉得 C 语言有关数组甚至指针……等等很多规定, 属于 C 语言这种语言本身的设计问题! 当然, 这跟发明者所处的时代有关, 或者发明者多少有些 "玩技术" 的倾向

正规的开发人员 ( 而不是玩技术的 ) 应该避开这些缺陷, 对于花哨玩意儿, 简单弱智点好. 完全可以参考 C++ 甚至 Java 的某些风格去写程序, 这些语言的一些规定其实也是在逐步修正 C 的问题.

使用特权

评论回复
14
simon21ic| | 2008-5-16 01:27 | 只看该作者

LS教训的是

其实本来就不想回复的,只是碰到HWM感兴趣,就随便聊聊而已,不用太计较
偶确实不是正规的开发人员,不然也不会找不到工作(可能自己不想找技术工作吧),这些对于偶确实只是玩具而已,没有必要太认真

PS:发过的那些贴怎么删啊?只有收藏和编译,没找到删除

使用特权

评论回复
15
wrainp|  楼主 | 2008-5-16 01:38 | 只看该作者

学习

学习了...

使用特权

评论回复
16
hotpower| | 2008-5-16 02:01 | 只看该作者

不懂~~~只知道&a是变量a定位地址的数值

使用特权

评论回复
17
computer00| | 2008-5-16 02:06 | 只看该作者

哈哈~~~你到keil下试下?结果发现a并不是一个变量,

而是一个常量,所以keil并不为它分配RAM空间,也就无所谓保存地址的问题。
编译器自己记住了a里面的值,并没有单独为a分配一个空间,所以在keil下,&a的值跟a的
值居然是一样的。本来也是,数组名是指针常量,编译器知道它的值是多少就行了,
没必要单独分配一个空间(实际上是放在程序段中了)来保存之,浪费空间。

这个跟函数名有点类似,函数名本来就是一个地址了,如果再取地址会怎样?
结果还是一样,返回的值还是函数地入口地址,而不是一个指向函数的指针
的地址。就算你在函数名前加100个&也是一样...

使用特权

评论回复
18
hotpower| | 2008-5-16 02:09 | 只看该作者

哈哈~~~那是Keil C51倒塌的事情,Keil ARM/Cortex M3就大不同了

使用特权

评论回复
19
computer00| | 2008-5-16 02:24 | 只看该作者

哈哈~~~大叔搞错了,&a不是保存的a的地址,它的值还是a...

不管是在C51下,还是CARM下,还是在VC下,我都试过,&a跟a的值是同一个。
也就是说,a本来就是一个指针,已经到尽头拉,再对它取地址,它只好耍无赖,
再对它取地址都无用了。但是对后面的加1操作却有着不同的做法。C51下&a+1是
只偏移一个int,而在VC下,却是5个int……

使用特权

评论回复
20
simon21ic| | 2008-5-16 12:03 | 只看该作者

就数值而言,确实都一样

就类型而言,不一样
int a[5];
a的类型是int[5],如果使用不会产生退化的操作运算,比如&,得到的结果还是那个指针,但类型不是int*,而是int(*const)[5],所以,+1操作其实是对这个地址+sizeof(int)*5
如果数组名是常量指针的话,那么指针的长度是多少?sizeof(a)是多少?a会被认为是一个指针,是在使用会引起的退化的运算中,a会退化为int*const的类型

诶,又有人讨论,又多说了一点

使用特权

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

本版积分规则

31

主题

79

帖子

1

粉丝