找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1927|回复: 15
收起左侧

关于单片机C语言指针、数组、变量的操作

[复制链接]
ID:824490 发表于 2022-3-14 17:22 | 显示全部楼层 |阅读模式
这是一个用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); //不知为啥,加入这行就出错,再次赋值不能?
  
  }
}
回复

使用道具 举报

ID:301191 发表于 2022-3-15 05:16 | 显示全部楼层
顶一下
回复

使用道具 举报

ID:311903 发表于 2022-3-15 08:34 | 显示全部楼层
出什么错
回复

使用道具 举报

ID:844772 发表于 2022-3-15 09:11 | 显示全部楼层
你这里多打了个*      //test2:   *real_addr= buf_16; //确定指针   另外,在51这是可以的,在其他编译器可能数字就不对了,主要高低位问题。
回复

使用道具 举报

ID:824490 发表于 2022-3-15 09:35 | 显示全部楼层

   tt=*(real_addr+3); //单字节赋值 tt=0x78;
   kk=*(real_addr+5);//kk=0xab;
   //tt=*(real_addr+7); //不知为啥,加入这行就出错,再次赋值不能?
出错的情况是这样的,如要tt只进行一次赋值,数值是对的,如要再进行一次赋值,前后2次都是错的,0x00!
回复

使用道具 举报

ID:824490 发表于 2022-3-15 09:39 | 显示全部楼层
glinfei 发表于 2022-3-15 09:11
你这里多打了个*      //test2:   *real_addr= buf_16; //确定指针   另外,在51这是可以的,在其他编译器 ...

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

回复

使用道具 举报

ID:311903 发表于 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;
回复

使用道具 举报

ID:844772 发表于 2022-3-15 10:56 | 显示全部楼层
你写的是 *real_addr= buf_16,应该是 real_addr= buf_16,否则你是把地址赋值给指针内容了,但你又没有给指针分配空间。
回复

使用道具 举报

ID:401564 发表于 2022-3-15 13:26 | 显示全部楼层
指针要指向相同的变量吧
8位指向16位是会有警告的
指针不是应该用real_addr=& buf_16来取得数组的地址吗?
指针不怎么用,我基本就是这么认为的
回复

使用道具 举报

ID:624769 发表于 2022-3-15 14:02 | 显示全部楼层
编译没有问题,可以正常通过, 如下: 指针问题.png

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

指针问题2.png

回复

使用道具 举报

ID:824490 发表于 2022-3-15 14:26 | 显示全部楼层
谢谢楼上各位大神!
我也是刚刚开始研究指针,所有的代码都是恁空想当然地码出来的。没有经过系统的学习,毕竟搬砖糊口、生活不易
我再捣腾捣腾,有什么问题再请教大家。先谢!
回复

使用道具 举报

ID:824490 发表于 2022-3-15 14:28 | 显示全部楼层
188610329 发表于 2022-3-15 14:02
编译没有问题,可以正常通过, 如下:

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

你这边的tt,第一次赋值和第2次赋值都正常吗?
回复

使用道具 举报

ID:824490 发表于 2022-3-15 14:29 | 显示全部楼层
xws245925587 发表于 2022-3-15 10:42
首先,你这个有以下几个问题
1、unsigned int ,在16位机器上,是16位,但是在32位机器上就是32位,因此 ...

谢谢我再试试
回复

使用道具 举报

ID:824490 发表于 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时, 是变量存放地址,这个变量只能按普通变量来操作,不能按批针来操作。两种代码的值是一样的,当意义不同。


欢迎指正!
回复

使用道具 举报

ID:624769 发表于 2022-3-15 14:42 | 显示全部楼层
名字不是重点 发表于 2022-3-15 14:28
你这边的tt,第一次赋值和第2次赋值都正常吗?

我这边直接拷贝的你的代码, debug 出来是正常的。MCU选的 STC89C51, AT89C51 Memory Model: Small 都是一样的结果。你看看你这边的设置吧。
回复

使用道具 举报

ID:824490 发表于 2022-3-15 14:44 | 显示全部楼层
188610329 发表于 2022-3-15 14:42
我这边直接拷贝的你的代码, debug 出来是正常的。MCU选的 STC89C51, AT89C51 Memory Model: Small 都是 ...

好的,谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表