打印

谁帮忙看下这个简单的C51程序

[复制链接]
3047|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yczhang|  楼主 | 2008-1-11 11:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序如下: void delay(unsigned char i) { while(i--) { ; } } main() { unsigned char i,k; while(1) { i=8; delay(i); i=7; delay(i); k=10; } } 我想问的是:为什么i=7;那一行程序总是不被编译呢?如下是在伟福界面和keil界面下的图片  

相关帖子

沙发
yczhang|  楼主 | 2008-1-11 11:42 | 只看该作者

程序

void delay(unsigned char i)
{
  while(i--)
    {
     ;
    }
}
main()
{
  unsigned char i,k;
  while(1)
  {
  i=8;
  delay(i);
  i=7;
  delay(i);
  k=10;
  }
}
编译器的意思是我那行程序i=7;没有用,怎么解决这个问题呢

使用特权

评论回复
板凳
kine8393| | 2008-1-11 11:43 | 只看该作者

delay中的WHILE后面要么用;要么用{}

使用特权

评论回复
地板
yczhang|  楼主 | 2008-1-11 11:47 | 只看该作者

2

while那块的程序先不用管(以前while后面的括号里有程序的),现在主要的问题是i=7;那行程序怎么总不被编译呢?

使用特权

评论回复
5
dai_weis| | 2008-1-11 14:12 | 只看该作者

你的 i = 7 后面的 delay(i)

中I是多少?如果是7则编译器认为i=7是个常量,略过了

使用特权

评论回复
6
yczhang|  楼主 | 2008-1-11 14:48 | 只看该作者

不明白

‘如果是7则编译器认为i=7是个常量’,这句话是什么意思呢,编译器为什么把这个赋值语句当作一个常量呢?

使用特权

评论回复
7
computer00| | 2008-1-11 15:22 | 只看该作者

实际上是被编译了的,不信你可以看生成的汇编代码。

调用函数时传递的的确是7。没有写回到i倒是事实,因为编译器认为后面不再用i了,所以就没有回写。

如果你将下面的k=10改成k=i,那么就会将7写回到i,并且keil编译器不会直接使用立即数7,而用一条减1指令,从前面的8减1变成7。

使用特权

评论回复
8
yczhang|  楼主 | 2008-1-11 17:25 | 只看该作者

8

汇编程序里果然已经把那行程序编译了,00说的太对了

使用特权

评论回复
9
lby100918| | 2008-1-12 23:45 | 只看该作者

为什么不把7直接写进去,如:delay(7);

使用特权

评论回复
10
ccl_love_u| | 2008-1-13 16:05 | 只看该作者

oo就是oo

使用特权

评论回复
11
sz_kd| | 2008-1-13 16:40 | 只看该作者

编译过

若将后运行delay()程序中换成
while(j--)看看,i一定是7

使用特权

评论回复
12
yczhang|  楼主 | 2008-1-13 19:34 | 只看该作者

12

回9楼,因为这是我的实验程序,没什么用,主要是一开始没明白不编译i=7;的那个现象

使用特权

评论回复
13
yczhang|  楼主 | 2008-1-14 13:02 | 只看该作者

还有两段程序

程序1:
#include <reg52.h>
sbit bit0=ACC^0;
sbit P10=P1^0;
main()
{
  unsigned char i,k=0x40;
  while(1)
  {ACC=k--;
   for(i=0;i<8;i++)
     {
        ACC=ACC>>1;
        P10=bit0;
      }
  }
}
程序2:
#include <reg52.h>
sbit bit0=ACC^0;
sbit P10=P1^0;
main()
{
  unsigned char i,k=0x40;
  while(1)
  {ACC=k--;
   for(i=8;i>0;i--)
     {
        ACC=ACC>>1;
        P10=bit0;
      }
  }
}
程序的主要目的就是把十六进制数据k串行发送到IO口P1.0。可是如果用程序1就达不到目的,因为程序走到for循环后就把A清0了,而用程序2的话就没事,程序走到for循环后不会把A清0。请问原因是什么?

使用特权

评论回复
14
yexinkfrqw| | 2008-1-14 21:25 | 只看该作者

这应该是编译器的问题

在反汇编中可以看到后一种ACC的确没有被清0
我想应该是编译器代码优化的原因。
顶7楼,让学到一种发现问题的好方法!

使用特权

评论回复
15
yixing2003| | 2008-1-15 02:02 | 只看该作者

volatile

volatile int i;

使用特权

评论回复
16
hotpower| | 2008-1-15 02:06 | 只看该作者

严重同意楼上~~~

使用特权

评论回复
17
yczhang|  楼主 | 2008-1-15 11:07 | 只看该作者

volatile在这里不管事

我试过加上volatile,不管事的。反正程序1的汇编程序里总是先CLR A,再MOV i,A而程序2的汇编程序就是一个简单的mov i,#8

使用特权

评论回复
18
computer00| | 2008-1-15 11:25 | 只看该作者

晕...谁叫你C语言里还用ACC啊...晕死..

使用特权

评论回复
19
alice84| | 2008-1-15 11:29 | 只看该作者

使用ACC会被当成汇编吗?

ACC不就是一个名吗/

使用特权

评论回复
20
computer00| | 2008-1-15 12:35 | 只看该作者

但是它是A累加器...C语言里面本来是看不到这个东西的...

使用特权

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

本版积分规则

60

主题

454

帖子

0

粉丝