0

关于投票
倒塌了~~~MSP430什么都不明白就debug了

实在是一只老菜鸟~~~等着周一的2008年"430 Day"研讨会吧~~~

到时最好别迷糊~~~

看来所有的IAR编译器几乎都是一样的~~~

点击看大图

系统分类: 单片机
用户分类: MSP430
标签: 无标签
来源: 原创
发表评论 阅读全文(171) | 回复(0)

0

关于投票
00要误导一大片了---再论C语言指针问题

俺本不想再参与如此"低等"的问题,可是俺不能看着"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++上就要漫天找错了~~~
系统分类: 单片机
用户分类: Keil C51
标签: 无标签
来源: 整理
发表评论 阅读全文(184) | 回复(0)

0

关于投票
郁闷+求助~~~不知2008年"430 Day"研讨会的时间表

有知道的请告诉菜农一下,免得错过好时光~~~

谢谢!!!  HotPower@126.com

hotpower 发表于 2008-5-17 17:17 德州仪器(TI) ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖


楼主: 郁闷+求助~~~不知2008年"430 Day"研讨会的时间表

谢谢!!!

点击看大图

 

hotpower 发表于 2008-5-17 17:20 德州仪器(TI) ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

2楼: 不知这个研讨会的日程表对否???

再次感谢!!!

点击看大图

系统分类: 单片机
用户分类: MSP430
标签: 无标签
来源: 整理
发表评论 阅读全文(155) | 回复(2)

0

关于投票
C语言指针问题

激烈讨论见: http://bbs.21ic.com/club/bbs/list.asp?boardid=11&page=1&t=2963283

俺觉得搞笑~~~

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

楼主: C语言指针问题

main()
{
  int a[5]={1,2,3,4,5};
   int *ptr=(int *)(&a+1);
   printf("\n%d,%d",*(a+1),*(ptr-1));
}

输出结果是多少?
  请解释一下原因...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

24楼: 哈哈~~~俺用&a没错过呀~~~

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

26楼: to 24楼:确实,所以这些讨论没有意义

&a+1,这种写法就更本不推荐在程序中使用(或者使用的话,加上强制类型转换),并不是所有编译器都严格按照标准的,特别是8位的MCU的编译器,需要考虑MCU限制和效率问题等。

偶大概翻译一下:
3 Except when it is the operand of the sizeof operator or the unary & operator, or is a
  string literal used to initialize an array, an expression that has type ‘‘array of type’’ is
  converted to an expression with type ‘‘pointer to type’’ that points to the initial element of
  the array object and is not an lvalue. If the array object has register storage class, the
  behavior is undefined.

3.出了作为sizeof,&,或者用于初始化一个数组的字符串外(?),一个具有'array of type'类型的表达式会转化为'pointer to type',并指向数组的第一个单元,并且不能作为左指。。。。

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

28楼: 讨论确实没意思~~~俺坚持&a是取变量a所在地址值别人随便去理解吧

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

31楼: 只有一种规则!

只有一种规则!它实际上是以一种相当优雅的方式把我们这些完全不同的概念联系在一起。


《C与指针》P141:
    首先让我们学习一个概念,它被许多人认为是C语言设计的一个缺陷。但是,这个概念实际上是以一种相当优雅的方式把一些完全不同的概念联系在一起的。

考虑下面的声明:
  int a[5];
   a[1]的类型是整型,那a的类型又是什么?它所表示的又是什么?一个合乎逻辑的答案是它表示整个数组,但事实并非如此。
   
   在C中,在几乎所有使用数组名的表达式中,数组名的值是一个指针常量,也就是数组第一个元素的地址。它的类型取决于数组元素的类型:如果它们是int类型,那么数组名就是“指向int的常量指针”;如果它们是其它类型,那么数组名的类型就是“指向‘其他类型’的常量指针”。
   数组具有一些和指针完全不同的特征。例如,数组具有确定数量的元素,而指针只是一个标量值。编译器用数组名来记住这些属性。只有数组名在表达式中使用时编译器才会为它产生一个指针常量。
   注意这个值是指针常量,而不是指针变量,你不能修改常量的值。你只要稍微回顾一下,就会认为这个限制是合理的:指针常量所指向的是内存中数组的起始位置。如果修改这个指针常量,唯一可行的操作就是把整个数组移动到内存的其他位置。但是,程序完成链接之后,内存中数组的位置是固定的。所以当程序运行时,再想移动数组就为时已晚了。因此,数组名的值是一个指针常量。

    只有在两种场合下,数组名并不用指针常量来表示:
1、当数组名作为sizeof操作符的操作数时:sizeof返回整个数组的长度,而不是指向数组的指针的长度。
2、当数组名作为单目操作符的操作数时:取一个数组名的地址所产生的是一个指向该数组的指针,而不是一个指向某个指针常量值的指针。

个人看法:既然说了“在C中......”那么现今所有的C都符合这个“相当优雅的”规则。如果是“有的C编译器这样,另一些编译器那样,......”那么这本世界流行的《C与指针》还不如我们这场讨论有价值?


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

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

俺喜欢C++和delphi,讨厌C,所以干什么都先想到"数组"或结构(类)~~~

例如俺这几天发了一帖水文:DSP5402之另类的"数组"访问
是dsp访问外部存储器的问题,它实际是访问的数组.

#define FLASH(x)  (*((volatile unsigned char *) 0x8000 + x))
/*----------------------------------------------------------
另类的"数组"访问,外扩的SST39VF800A从0x8000开始
void FlashObj::ChipErase(void)
{
  FLASH(0x5555) = 0xaa;  
  FLASH(0x2AAA) = 0x55;  
  FLASH(0x5555) = 0x80;
  FLASH(0x5555) = 0xaa;  
  FLASH(0x2AAA) = 0x55;  
  FLASH(0x5555) = 0x10;
  Wait(0x5555);
}
void FlashObj::Wait(unsigned int address)
{
unsigned int temp, val;
  do {
    val = FLASH(address);
    __nop();
    temp = FLASH(address);
    __nop();
  }
  while(((val ^ temp) & (1 << BIT6)) != 0);
}
----------------------------------------------------------*/
点击看大图

再有个真数组的水文: DSP281X变量地址数组定位方法

细心的人会看出来:

优秀的编译器对指针/数组/结构成员变量/结构指针的成员变量
等访问最终的优化代码几乎是相同的.

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

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

如果:
xdata unsigned i;

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

系统分类: 单片机
用户分类: Keil C51
标签: 无标签
来源: 整理
发表评论 阅读全文(145) | 回复(0)
总共 , 当前 /