OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4724|回复: 9

关于结构体指针和结构体

[复制链接]

36

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2014-10-27
在线时间
34 小时
发表于 2015-9-30 11:25:47 | 显示全部楼层 |阅读模式
5金钱

在学习原子哥USB实验的时候,看到代码USB初始化如下:

void USB_Init(void)
{
 pInformation = &Device_Info;
 pInformation->ControlState = 2;
 pProperty = &Device_Property;
 pUser_Standard_Requests = &User_Standard_Requests;
 /* Initialize devices one by one */
 pProperty->Init();
}

关于上面代码,为什么这边要先把结构体变量的指针赋值给 pInformation,然后再pInformation->ControlState = 2;如果这边直接写成 Device_Info.ControlState = 2;可以吗?

还有最后一句写成Device_Property.Init();可以吗?


另外,在USB中断处理函数中:

void USB_Istr(void)
{   
  wIstr = _GetISTR();

#if (IMR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
  {
    _SetISTR((u16)CLR_RESET);
    Device_Property.Reset();
#ifdef RESET_CALLBACK
    RESET_Callback();
#endif
  }
#endif....

上面又写成了这种变量模式,没有使用指针,若写成pProperty->Reset();是否可行?

上面这两种写法的区别在哪,主要是为何考虑?

谢谢!

最佳答案

查看完整内容[请看2#楼]

问题1:在这里pInformation->ControlState = 2 和 Device_Info.ControlState = 2的效果是一样的。 问题2:写成Device_Property.Init();也是可以的 问题3:如果定义了pPropertyp = &Device_Property;,使用Property->Reset();也是可以的 如果说结构体实体在这个文件中可见,我觉得直接用结构体Device_Property.XXX的操作和用结构体指针pInformation->XXX的效果是一样的,操作的内 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2015-9-30 11:25:48 | 显示全部楼层
问题1:在这里pInformation->ControlState = 2 和 Device_Info.ControlState = 2的效果是一样的。
问题2:写成Device_Property.Init();也是可以的
问题3:如果定义了pPropertyp = &Device_Property;,使用Property->Reset();也是可以的

如果说结构体实体在这个文件中可见,我觉得直接用结构体Device_Property.XXX的操作和用结构体指针pInformation->XXX的效果是一样的,操作的内存也是相同,个人习惯上喜欢用指针的方式,例如结构体是个数组Device_Property[channnel_x].xxx,那我会pInformation = &(Device_Property[channel_x]); 这样的话我就不用在关心数组下标(不同的通道),让自己的代码更关注与具体实现;代码整体也能简洁一些;

如果说这个结构体不在这个文件中,而且通过其他方式传递的指针,那只能用结构体指针的方式实现,那就和上面情况用指针的习惯一致

对我而言,用指针可以养成统一的习惯,而用结构体或许能省个指针变量的内存。
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

2

主题

239

帖子

0

精华

高级会员

Rank: 4

积分
545
金钱
545
注册时间
2015-6-5
在线时间
110 小时
发表于 2015-9-30 13:16:26 | 显示全部楼层
寫程式分成幾個階段
1 初階:能動就好
2 中階:開始注意變數名稱與功能是否相符,增加程式可讀性
3 高階:盡可能模組化功能 覆用性功能獨立成一個函數 重覆呼叫,結構體的使用
4 神人:讓你呼叫幾個函數就能用這個功能

基本上這種公用庫的東西 都是神人寫好給你用的
如果你等級不夠高 硬要去讀這些東西 你會想死

另外你的問題
你需要先搞懂
uint8_t *a;
*a 跟 &a 的差異
回复

使用道具 举报

19

主题

702

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3339
金钱
3339
注册时间
2013-7-30
在线时间
708 小时
发表于 2015-9-30 13:53:42 | 显示全部楼层
楼上正解,模块化编程很重要
思想很重要,无论做人还是编程!
我的技术公众号【微联智控工作室】
回复

使用道具 举报

36

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2014-10-27
在线时间
34 小时
 楼主| 发表于 2015-10-7 09:04:11 | 显示全部楼层
回复【2楼】Rocks:
---------------------------------
谢谢Rocks的解答,*a和&a,前者为指针,这个指针占内存,后者取地址,不占内存,不知道理解的对不对。
回复

使用道具 举报

36

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2014-10-27
在线时间
34 小时
 楼主| 发表于 2015-10-7 09:05:28 | 显示全部楼层
回复【4楼】ianhom:
---------------------------------
谢谢ianhom的解答,解释的非常清楚!
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2015-10-7 22:09:22 | 显示全部楼层
回复【2楼】Rocks:
---------------------------------
“另外你的問題,你需要先搞懂uint8_t *a;*a 跟 &a 的差異”
对rocks兄最后的问题,我不知道这样理解对不对:“前提是uint8_t *a, 在这个前提下*a和&a的差异”
如果我这个问题这么理解的话,那a是一个指向uint8_t类型的指针变量,*a就是a所指的那个uint8_t变量,&a就是存放这个uint8_t指针的地址。
假设
uint8_t   b = 0x55;    // b的地址为0X2000 0000
uint8_t *a;                  //定义一个uint8_t类型的指针变量a,该指针变量的地址为0x2000 0400
a = &b;                     // 指针变量a指向变量b

这样
a 的值为 0x2000 0000;         uint8_t变量的地址
*a的值为 0x55;                     uint8_t变量
&a的值为0x2000 0400 ;        指向uint8_t变量的指针变量的地址

不知道我这样理解对不对
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

2

主题

239

帖子

0

精华

高级会员

Rank: 4

积分
545
金钱
545
注册时间
2015-6-5
在线时间
110 小时
发表于 2015-10-8 09:42:42 | 显示全部楼层
&a的值为0x2000 0400 ;

a 本身就是指針數值了
當你 a=&b時 a已改變指針數值

回過頭看那段程式 兩種用法差異

先宣告了一個struct
struct Num
{
  uint8_t Int;
}

#1
struct Num a;
void function()
{

}

#2
void function(struct Num * a)
{

}

這兩種情況下 function裡面, 我要對 a的Int做更動
我該怎麼寫?
回复

使用道具 举报

36

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2014-10-27
在线时间
34 小时
 楼主| 发表于 2015-10-9 18:01:41 | 显示全部楼层
回复【7楼】ianhom:
---------------------------------
我认为你说的对的。
回复

使用道具 举报

36

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2014-10-27
在线时间
34 小时
 楼主| 发表于 2015-10-9 18:07:52 | 显示全部楼层
回复【8楼】Rocks:
---------------------------------
#1里面a.Int=***;这个函数没参数
#2里面a->Int=***;调用function(&a);
Rocks是想说函数无法改变实参的问题还是我理解的不对?我迷糊了。。。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 12:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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