OpenEdv-开源电子网

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

不好意思,C语音基础差,没看懂这是什么意思

[复制链接]

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
发表于 2016-5-11 14:16:40 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 vention 于 2016-5-11 14:17 编辑

第一个宏定义 定义了后面的LCD 是*** 。 不懂了,看不懂是定义了LCD什么。
1.png
2.png
3.png

最佳答案

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

“->”符号,其实和“.”符号功能一样,都是取结构体中的成员,只不过“->”符号用在指针结构体中,“.”符号用在普通结构体中。谢谢。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

20

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
494
金钱
494
注册时间
2015-7-3
在线时间
55 小时
发表于 2016-5-11 14:16:41 | 显示全部楼层
“->”符号,其实和“.”符号功能一样,都是取结构体中的成员,只不过“->”符号用在指针结构体中,“.”符号用在普通结构体中。谢谢。
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-5-11 21:04:57 | 显示全部楼层
数据结构是数据的组织方式的说明,比如说
typedef struct _TA
{
    unsigned char u8A;
    unsigned char u8B;
    unsigend char u8C;
    unsigend char u8D:
}TA;

这样就定义了一个结构体“类型”TA,可以用TA来定义一个类型为TA的结构体“实体”。例如:
TA tA;// tA是结构体实体,结构体类型是TA,里面有4个unsigned char类型的数据
tA.u8A = 1;
tA.u8B = 2;
tA.u8C = 3;
tA.u8D = 4; //  "."符号是结构体“实体”tA访问成员的符号,如果tA是个指针,那就需要用“->”

强调一下这里TA表示的是结构体的“类型”,可以定义TA类型的指针,表明该指针的值是一个TA结构体实体的地址。进一步来讲,如果我指定一个地址,并强制转换数据类型为(TA*),那这个地址后面的数据就按照TA的格式布局来解读。例如
unsigned int u32A = 0x11223344;   //定义一个32位的变量,值为0x11223344,假设变量的地址为0x20000000;
TA * ptA = (TA *)(&u32A);            //定义一个TA类型的指针,并且把u32A的地址0x20000000赋值给这个指针变量
                                                //那就指明了0x20000000这段的内存按照TA结构的数据组织方式来理解数据。
                                                //假设为大端模式,高位数据在低位地址
                                                //ptA->u8A的值为0x11,地址为0x20000000;
                                                //ptA->u8B的值为0x22,地址为0x20000001;
                                                //ptA->u8C的值为0x33,地址为0x20000002;
                                                //ptA->u8D的值为0x44,地址为0x20000003;
这样这个u32A的32位整型变量就可以作为TA类型的数据来理解---4个8位char型数据。

再回到楼主的问题
LCD_BASE是一个地址   (对应于上例中u32A的地址0x20000000)
LCD_TypeDef是一个结构体类型  (对应上例中的TA)
((LCD_TypeDef *)LCD_BASE)就是把LCD_BASE这个地址数据以LCD_TypeDef的格式来理解  (对应上例中的(TA *)(&u32A))
LCD就表示上述的((LCD_TypeDef *)LCD_BASE)这个地址  (对应上例中的ptA = (TA *)(&u32A))
LCD->LCD_REG就表示按照LCD_TypeDef格式解读第一个结构体成员  (对应上例中的ptA->u8A)
LCD->LCD_RAM就表示按照LCD_TypeDef格式解读第二个结构体成员  (对应上例中的ptA->u8B)

总结来说,通过LCD_TypeDef这个结构体类型来解读地址为(0x6C000000 | 0x0000007E)及其后面的数据。
以上仅仅从C语言的角度的解释,中间还有很多概念没有详述,可以看看C语言方面的书。
从功能角度来说,只要理解这个LCD就代表LCD的操作即可
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

55

主题

1231

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2625
金钱
2625
注册时间
2014-2-13
在线时间
514 小时
发表于 2016-5-11 22:54:44 | 显示全部楼层
LZ需要学习指针和结构体
技术交流,Sell 中颖单片机,欢迎私信骚扰
回复

使用道具 举报

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
 楼主| 发表于 2016-5-12 11:31:56 | 显示全部楼层
本帖最后由 vention 于 2016-5-12 11:44 编辑

ianhom 发表于 2016-5-11 21:04
数据结构是数据的组织方式的说明,比如说
typedef struct _TA
{

哇,好感谢你的这么耐心解答,看完你的例子解释之后,突然明白了很多。不过,我还有一个小小的疑问。
3.png
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-5-12 11:54:44 | 显示全部楼层
1.
因為LCD_BASE不是變量 它本身就是(u32)0xxxxxxxxx ,取址是對變量用的...這個你能自己加上& 看編譯器跟你說啥就知道不必問的....

2.
LCD_TypeDef *LCD=(LCD_TypeDef *)LCD_BASE; 之後直接操作LCD->底下的東西也可以 這應該沒有為什麼
或者 LCD_TypeDef *LCD __attribute__ ((at(LCD_BASE))); 直接操作LCD.成員 應該也可以 但在不同的編譯器上可能有問題

3.
你第一個會報錯吧  #define 有命名規則的 這個也是能自己試的根本不必問...

給你點建議...單純程式方面的問題就算是新手也能自己驗證是不是跟自己所想的一樣...而且這不需花太多時間 自己得來的又能理解的夠透徹....加油~~~~~
回复

使用道具 举报

26

主题

261

帖子

1

精华

高级会员

Rank: 4

积分
734
金钱
734
注册时间
2013-11-1
在线时间
28 小时
发表于 2016-5-12 12:06:08 来自手机 | 显示全部楼层
楼主求知的精神值得鼓励,但是方法不推荐,最好去了解一下相关知识再问
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-5-12 14:03:55 | 显示全部楼层
vention 发表于 2016-5-12 11:31
哇,好感谢你的这么耐心解答,看完你的例子解释之后,突然明白了很多。不过,我还有一个小小的疑问。

6楼的朋友已经很好地回答你的问题  @civic7366

&是取地址符,&u32A就可以得到u32A这个变量的地址,而LCD_BASE本身就是个地址,所以不需要用&。(在C语言书籍中可以看看指针部分,“&”和 “*”的说明)

是#define,不是#defined。

如果是#define *LCD   (LCD_TypeDef*)(LCD_BASE),这里宏定义命名规则同变量命名规则,不能用这样*LCD的命名,编译器会报错。我觉得你想问的是6楼所说那种情况,即LCD_TypeDef *LCD=(LCD_TypeDef *)LCD_BASE;这样也是可以使用LCD->LCD_REG的,不过需要注意的是,这时候LCD不是宏,而是指针变量,需要占用内存的,即LCD的值是可以变得,LCD可以指向其他地址。

我解释的不是很清楚,可以在看看c语言方面的书籍,再动手做做试验,会豁然开朗~
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
 楼主| 发表于 2016-5-12 15:09:52 | 显示全部楼层
本帖最后由 vention 于 2016-5-12 15:10 编辑
ianhom 发表于 2016-5-12 14:03
6楼的朋友已经很好地回答你的问题  @civic7366

&是取地址符,&u32A就可以得到u32A这个变量的地址, ...

#defined   和 #define 纯属笔误。

我不明白的是  #define LCD_BASE  ((u32)0x……)   这个LCD_BASE本身就是个地址,这点我是不知道的。
#define <名字> 后面跟的就是一个常量。 一直都清楚用这个常量,可以用这个<名字> 来代替的。 但是  ((LCD_TypeDef *)LCD_BASE)  就等同于  ((LCD_TypeDef *)(u32)0X……)
那(u32)0X……不是本身就是个确定的常量来的么   然后就开始混乱了。就会想,啊,这为什么是个常量,不是个变量取址。 我不是要取个地址强制变成(LCD_TypeDef *)  然后用LCD来代替的么,怎么是个常量,一个确切的(u32)0x……。  然后我就又混乱了。
怎么#define LCD_BASE ((LCD_TypeDef *)(u32)0X……)   LCD_BASE变成一个地址了,不是一个常量么。就这么混乱了……
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-5-12 16:37:18 | 显示全部楼层
vention 发表于 2016-5-12 15:09
#defined   和 #define 纯属笔误。

我不明白的是  #define LCD_BASE  ((u32)0x……)   这个LCD_BASE ...

混乱是正常的,都要经历的过程
数据本身可以理解为值,也可以理解为地址,这个取决于你的操作。
很多时候对于外设的寄存器就是这么处理的,因为外设寄存器的地址是固定的,所以直接用个常量,这个常量的值为这个外设寄存器的地址即可,常量的值可以是个地址。
变量取值是不得不采取的办法,因为变量一般在内存中申请的位置是不一定的,比如 static int a; 就是在内存的静态全局区申请一个变量,这个变量的地址是编译器分配给你的,这个地址用a来表示,如果想知道这个变量a的地址,就只能通过&取址。

在系统看看指针的书,找个板子做做试验就明白啦
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
 楼主| 发表于 2016-5-12 16:54:36 | 显示全部楼层
   非常感谢各位的耐心指导和解答。
回复

使用道具 举报

6

主题

46

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
305
金钱
305
注册时间
2014-3-24
在线时间
39 小时
发表于 2016-5-12 22:01:11 | 显示全部楼层
虽然楼下的各位都很耐心回单,但是对这种不好好看书,入门级问题都跑来问的人直接鄙视!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-27 05:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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