打印

51单片机C语言中应用指针时遇到的疑惑

[复制链接]
4450|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fzpxp|  楼主 | 2009-6-4 14:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
目的很简单:从其他设备读取9字节的数据,再通过串口显示出来

//ReadRAM函数完成连续读取外围设备9字节功能,并把9个字节依次放入指针address开始的位置
ReadRAM(uchar *address)
{    uchar i;
    
    for(i=0;i<9;i++)
        *(address+i)=ReadByte(); //ReadByte()执行一次读取一个字节
}
方法1
main()
{
    uchar ram;  //读取到的9个字节就放入从&ram开始的连续9个位置里
    while(1)
    {
    ReadRAM(&ram);    
    ReadSerial(&ram);//串口显示函数
    }
}


实际运行结果发现这样读取到得9字节数据不正确,而把main函数这样改一下读到得数据就对了
方法2
main()
{
    uchar ram[9];  //读取到的9个字节就放入数组ram[9]中
    while(1)
    {
    ReadRAM(ram);    
    ReadSerial(ram);//串口显示函数
    }

}
方法1,我是想通过定义uchar ram;让编辑器为ram分配一内存空间,从而得到一个内存地址&ram,把读到得9字节数据写入到此地址开始的9个字节中
方法2 是预先定义好9个字节的数组,把读到得数据写入此数组中
个人感觉是这两种方法应该都行啊,为什么方法2读到得数据正确,而方法1运行后读出的9字节数据是错误的呢?请高手指点

相关帖子

沙发
lanmp| | 2009-6-4 15:08 | 只看该作者

你只分配了1个字节却要写9个字节?

谁会给你留着后面8个空间?

使用特权

评论回复
板凳
耕在此行| | 2009-6-4 15:21 | 只看该作者

呵呵 你要向汇编一样指定一个起始地址

然后对后续的8个地址留着,那么第一种办法才行。
不达这么做的人应该是**挑一了。

使用特权

评论回复
地板
冷漠| | 2009-6-4 16:01 | 只看该作者

玩玩这个,借你的程序看看结果,学习学习。

方法2中
把“ uchar ram[9];  //读取到的9个字节就放入数组ram[9]中”

改为 uchar data *ram="12345678";  //定义了9个字节内存空间。

再试试玩玩下面这个:(现在的芯片都带片内xdata)

#include<stdlib.h>
#include<stdio.h>

main( )
{
char *ram;
init_mempool(0x0000,0x50);   //初始化xdata内存池。也许不需要这句。
ram=malloc(9);  // 动态为指针变量ram分配了9个字节的xdata存储空间。

 while(1)
    {
    ReadRAM(ram);    
    ReadSerial(ram);//串口显示函数
    }

free(ram);
}

使用特权

评论回复
5
xwj| | 2009-6-4 16:04 | 只看该作者

2楼正解,其他的都是歪门邪道

使用特权

评论回复
6
zhouxinxin1980| | 2009-6-4 16:27 | 只看该作者

xwj PK 冷漠

沙发

使用特权

评论回复
7
lanmp| | 2009-6-4 17:02 | 只看该作者

既然用C,最好让编译器完成该由它完成的工作。

否则可以用汇编,想怎么搞就怎么搞。

使用特权

评论回复
8
fzpxp|  楼主 | 2009-6-4 17:59 | 只看该作者

回复2楼

方法1中,虽然只定义一个字节ram,比如编辑器给它分配内存地址是0XD1,但是函数ReadRAM(uchar *address)可以通过这个地址把数据写入到0XD1-0XD9啊,但是为什么这样不行呢?
我用这种方法在TC2.0上编写了个程序,结果是对的
哪位能解释一下吗?

使用特权

评论回复
9
冷漠| | 2009-6-4 18:24 | 只看该作者

回8楼:

以前在哪本书上看过“定义了一个指针,就相当于定义了一个数组。”觉得没错。

后来看到“*ptr 和 ptr[ ]相同吗?”完全不同!仅在函数形参时才是相同的。所以“定义了一个指针,就相当于定义了一个数组。”忘了前提条件了。

那么,2楼的错误用法可以是:uchar *ram;

好的编译器通不过的。例如按照8楼的概念:从ram以后,使用200个字节都可以的?显然编译器不会同意。

关于数组越界防止,highgear和zyboy讲得更好。看看他们的帖子。

使用特权

评论回复
10
lanmp| | 2009-6-4 18:26 | 只看该作者

这个和编译器相关

我猜你在51里面的程序不止这么点,而在TC里面只有这么两部分,而且子程序都在Main前面,对么?

使用特权

评论回复
11
mohanwei| | 2009-6-4 18:31 | 只看该作者

这年头……

使用特权

评论回复
12
冷漠| | 2009-6-4 18:51 | 只看该作者

5楼版主说的没错。

以前国际上每年有一个C语言什么另类应用大赛。大意是谁能用C解出评委出的题目,奇思妙想——“怪异思维”者获胜,奖金美元不少。——如果有两个人想的一样的解答都不能算获胜,冠军只有一个。(据杨振宁自述,他过去有一段时间曾热心过这类比赛,每次5万$奖金。)

这正是中西方教育的不同:美国人的教育:你一定与别人不同,哪位同学要是和别人活的一样,他肯定一生心里不痛快,这世界上本来人口就多,我是不是多余的人?

而中国大学出来的都一个样,那岂不是说都是多余的人?难怪失业率越来越高。俺一个人占着位子,可能公司就可以少招至少5个新人。俺抢了5个人的饭碗?最近一直考虑这个问题,是不是应该辞职回家,俺早就这辈子饿不死了。

所以,旁门左道者,和别人不一样者,优胜获奖。他不会想自己是不是多余的人这类问题。平时多训练一些与别人不一样的方法,就不会在失业大军里了。

使用特权

评论回复
13
fzpxp|  楼主 | 2009-6-4 19:33 | 只看该作者

回复10楼

我猜你在51里面的程序不止这么点,而在TC里面只有这么两部分,而且子程序都在Main前面,对么?
确实是这样的。
我猜测是方法1中未定义的第二到第九个字节地址,被其他变量或程序重新写进去数据了,观察读到得结果也貌似这样:第一个字节读到得数据正确,第二到九都不对。
    while(1)
    {
    ReadRAM(&ram);    
    ReadSerial(&ram);//串口显示函数
    }
但是ReadRAM(&ram); 确实已经执行到了while(1)死循环中的最后了,没有可能其他变量再被定义了,难道是后面的ReadSerial(&ram);函数搞的鬼?他用到了第二到底九字节的地址,从而改写了里面的数据了?
是不是ReadRAM(&ram);后面没有再定义变量第一个字节后面的内存就不会被写入数据?
还是只要ReadRAM(&ram);后面存在函数或语句第二到底九字节的地址都有可能被重新占用?是不是把ReadSerial(&ram);删除掉就行了,但是这样又没法验证读的结果了,

    while(1)
    {
    ReadRAM(&ram);    
 
    }

使用特权

评论回复
14
lanmp| | 2009-6-22 14:11 | 只看该作者

肯定是这样的。

想看结果办法很多,你没有仿真器么?

使用特权

评论回复
15
不亦心| | 2009-6-22 14:56 | 只看该作者

绝对支持12楼

12楼说的太对了:

所以,旁门左道者,和别人不一样者,优胜获奖。他不会想自己是不是多余的人这类问题。平时多训练一些与别人不一样的方法,就不会在失业大军里了。


* - 本贴最后修改时间:2009-6-4 18:53:13 修改者:冷漠



八仙过海,各显神通嘛



使用特权

评论回复
16
huangqi412| | 2009-6-22 16:54 | 只看该作者

又pk?

使用特权

评论回复
17
逐梦青萍| | 2009-6-22 20:35 | 只看该作者

pk很好啊,为什么不喜欢

我觉得这种方式很好啊,又不涉及人身攻击,又能让参与者与旁观者得到启发,很好的一种学习方式。我喜欢

使用特权

评论回复
18
sheenhero| | 2009-6-22 20:52 | 只看该作者

支持冷漠

不单学了程序,更受启发,思维差异化,决定了人的定位

使用特权

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

本版积分规则

15

主题

47

帖子

0

粉丝