标题: 关于单片机C语言指针、数组、变量的操作 [打印本页]

作者: 名字不是重点    时间: 2022-3-14 17:22
标题: 关于单片机C语言指针、数组、变量的操作
这是一个用u8变量读取u16数组的代码,一种是u8数组的方式拆解u16数组,一种是直接赋值到u8变量的方法,直接赋值貌似不好用,多次赋值会出错?
有没有大神高手来指点一下?

typedef        unsigned char        u8;

typedef        unsigned int         u16;
u16  buf_16[4]={0x1234,0x5678,0x90ab,0xcdef};//16位双字节数组
void  main()
{


u8   buf_8[8];  //单字节数组
u8   *real_addr= buf_16; //定义一个指针,单字节型,指向双字节数组首址
u8  i;
u8  tt,kk;


//test1:


        for (i=0;i<8;i++)  //拆数组16bit到8bit
        {
         buf_8[ i]=*(real_addr+i); //赋值[ i]
        }
//到这里,buf_8[]={0x12,0x34,0x56,0x78,0x90,0xAB,0xCD,0xEF};

//test2:
  *real_addr= buf_16; //确定指针
   
while(1)
{


   tt=*(real_addr+3); //单字节赋值 tt=0x78;
   kk=*(real_addr+5);//kk=0xab;
   //tt=*(real_addr+7); //不知为啥,加入这行就出错,再次赋值不能?
  
  }
}

作者: 人工置顶员    时间: 2022-3-15 05:16
顶一下
作者: xws245925587    时间: 2022-3-15 08:34
出什么错
作者: glinfei    时间: 2022-3-15 09:11
你这里多打了个*      //test2:   *real_addr= buf_16; //确定指针   另外,在51这是可以的,在其他编译器可能数字就不对了,主要高低位问题。
作者: 名字不是重点    时间: 2022-3-15 09:35
xws245925587 发表于 2022-3-15 08:34
出什么错

   tt=*(real_addr+3); //单字节赋值 tt=0x78;
   kk=*(real_addr+5);//kk=0xab;
   //tt=*(real_addr+7); //不知为啥,加入这行就出错,再次赋值不能?
出错的情况是这样的,如要tt只进行一次赋值,数值是对的,如要再进行一次赋值,前后2次都是错的,0x00!
作者: 名字不是重点    时间: 2022-3-15 09:39
glinfei 发表于 2022-3-15 09:11
你这里多打了个*      //test2:   *real_addr= buf_16; //确定指针   另外,在51这是可以的,在其他编译器 ...

//test2:
//   *real_addr= buf_16; 这行注释后依旧出错。


作者: xws245925587    时间: 2022-3-15 10:42
本帖最后由 xws245925587 于 2022-3-15 10:44 编辑
名字不是重点 发表于 2022-3-15 09:35
tt=*(real_addr+3); //单字节赋值 tt=0x78;
   kk=*(real_addr+5);//kk=0xab;
   //tt=*(real_addr+ ...

首先,你这个有以下几个问题
1、unsigned int ,在16位机器上,是16位,但是在32位机器上就是32位,因此
你的0x1234,在32位机器上市0x00001234;
2、这里还有个大小端的问题,不同的处理器,可能大小端不一样,导致你取得数据也有错;
3、修改:将unsigned int 修改为 unsigned short int ,例如
typede unsigned short int  u16;
#pragma pack(1)
u16 buf_16....
#pragma pack()

你这个时候去取的数据应该没错了,有错的话,一般是大小端的问题

另外,你那里有个
//test2
*real_addr = buf_16,这个没啥意义,你这里是把 real_addr原先指向地址的内容给修改了,建议屏蔽,如果你只是想获取buf_16的首地址,改为real_addr = (u8*)buf_16;
作者: glinfei    时间: 2022-3-15 10:56
你写的是 *real_addr= buf_16,应该是 real_addr= buf_16,否则你是把地址赋值给指针内容了,但你又没有给指针分配空间。
作者: Y_G_G    时间: 2022-3-15 13:26
指针要指向相同的变量吧
8位指向16位是会有警告的
指针不是应该用real_addr=& buf_16来取得数组的地址吗?
指针不怎么用,我基本就是这么认为的
作者: 188610329    时间: 2022-3-15 14:02
编译没有问题,可以正常通过, 如下:

运行后, tt也能取到  0xEF 如下:




作者: 名字不是重点    时间: 2022-3-15 14:26
谢谢楼上各位大神!
我也是刚刚开始研究指针,所有的代码都是恁空想当然地码出来的。没有经过系统的学习,毕竟搬砖糊口、生活不易
我再捣腾捣腾,有什么问题再请教大家。先谢!

作者: 名字不是重点    时间: 2022-3-15 14:28
188610329 发表于 2022-3-15 14:02
编译没有问题,可以正常通过, 如下:

运行后, tt也能取到  0xEF 如下:

你这边的tt,第一次赋值和第2次赋值都正常吗?
作者: 名字不是重点    时间: 2022-3-15 14:29
xws245925587 发表于 2022-3-15 10:42
首先,你这个有以下几个问题
1、unsigned int ,在16位机器上,是16位,但是在32位机器上就是32位,因此 ...

谢谢我再试试
作者: 名字不是重点    时间: 2022-3-15 14:30
本帖最后由 名字不是重点 于 2022-3-15 14:38 编辑
Y_G_G 发表于 2022-3-15 13:26
指针要指向相同的变量吧
8位指向16位是会有警告的
指针不是应该用real_addr=& buf_16来取得数组的地址吗? ...

这种方法试过,当结果是出错的个人认为:当变量有前缀“*”时,说时这个变量只能是指针了,只能是指向地址。real_addr=& buf_16时, 是变量存放地址,这个变量只能按普通变量来操作,不能按批针来操作。两种代码的值是一样的,当意义不同。


欢迎指正!

作者: 188610329    时间: 2022-3-15 14:42
名字不是重点 发表于 2022-3-15 14:28
你这边的tt,第一次赋值和第2次赋值都正常吗?

我这边直接拷贝的你的代码, debug 出来是正常的。MCU选的 STC89C51, AT89C51 Memory Model: Small 都是一样的结果。你看看你这边的设置吧。
作者: 名字不是重点    时间: 2022-3-15 14:44
188610329 发表于 2022-3-15 14:42
我这边直接拷贝的你的代码, debug 出来是正常的。MCU选的 STC89C51, AT89C51 Memory Model: Small 都是 ...

好的,谢谢!




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1