原创 00要误导一大片了---再论C语言指针问题

2008-5-17 19:30 3152 3 3 分类: MCU/ 嵌入式

俺本不想再参与如此"低等"的问题,可是俺不能看着"00要误导一大片了~~~"


讨论处在: http://bbs.21ic.com/club/bbs/list.asp?boardid=11&t=2963283



hotpower 发表于 2008-5-17 16:04 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

32楼: c提倡指针反对数组,可delphi刚好相反~~~


00说的:在keil51上 a==&a   

俺认为可能纯属巧合~~~

如果:
xdata unsigned i;

若此时i==&i俺真的再不玩51了~~~   


wxj1952 发表于 2008-5-17 18:08 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

33楼: 圈圈说的是对的。


51C编译器在处理一个数组名/函数名时,首先从符号表中查询有没有这个名字:
1、如果有,那么它肯定也相应有固定的地址。这时将被编译为立即寻址或者直接寻址方式访问。如果用指针间接方式访问,那纯粹是“知易行难”。
2、如果符号表中没有这个名字(动态建立?)将采用指针间接寻址方式——指针用于访问无名地址。而数组和函数都是有名字的。
3、再举个例子:
int f(int);
int (*pf)(int)=f; // 本应写为...=&f;   这就像 pf=&f;/pf=f; 两者对编译器来说完全一样,“&”操作符只是显式地说明了编译器将隐式执行的任务。下面的3种函数调用方式,结果一样效率大不同。
f(55);        //直接寻址
(*pf)(55);  //间接寻址
pf(55);    //间接寻址

后两个式子编译代码完全一样。比第一个长N倍。

hotpower 发表于 2008-5-17 19:24 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

34楼: 00要误导一大片了~~~


正如wxj1952所述,在编译器优化时,C默认了很多强制转换,很多在C++上是不允许的,因为这样很不安全,应该显式的转换.

拿数组来说,第1个数值的位置就是数组的物理位置即存储地址.结构也类同.

所以,A,&A,&A[0]都表示数组的首地址.

例如:
            &A[0]  &A[1]  &A[2]
A数组地址  0x1000,0x1002,0x1004

            A[0]   A[2]   A[2]
A数组数值  0x00,  0x01,  0x02

而对于一般变量来说
             &a
a变量的地址 0x2000
              a
a变量的数值  0x00


用c语言来表述:
unsigned int A[3] at 0x1000 = {0,1,2};
unsigned int a    at 0x2000 = 0;

若:
unsigned int *p;
   p = A;
   p = &A[0];
   p = A[0];肯定错  因为左值是指针变量p,应该是指针即地址
                    而右值是数组第1个单元A[0]的数值而非地址本身!
但是我的A[0]内就是我需要的地址呢???当然是要做强制转换了
即:
   p = (unsigned int *)A[0];

但是一般变量很容易误导.
   p = &a;//正确
   p = a;//我晕!!!a的地址&a是0x2000,而0x2000的内容a是0.

以下都能通过吗???

   p = (unsigned int *)0x2000;//知道a的地址

   if (p == &a)
   {
      puts("这个俺明白");
   }
   if (p == a)
   {
      puts("这个是做梦吧,除非编译器认为左值是指针右值肯定为指针即a的地址");
   }
   else
   {
      puts("俺坚持p != a的说明");
   }


故菜农认为:
即使编译器认为左值是指针,右值肯定为指针即地址.
那么也应该养成区分a和&a的好习惯~~~

否则程序移植到C++上就要漫天找错了~~~
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条