OpenEdv-开源电子网

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

关于(u8*)TEXT_Buffer的理解,求大神帮帮忙!

[复制链接]

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
发表于 2016-1-25 17:24:09 | 显示全部楼层 |阅读模式
1金钱
我现在看的是探索者F4  I2C总线


QQ图片20160125171506.png
1.png

const u8 TEXT_Buffer[]={"!GoodBody!"};  这句话是创建一个数组吧,每个数组元素是一个字节的意思吧?
(u8*)TEXT_Buffer  这句话是指针的强制类型转换,转换为u8类型指针的意思吧?也就是将这个数组转化为一个u8类型指针的指针对吧?


QQ图片20160125171601.png
这个是这个函数的具体内容.
pBuffer=(u8*)TEXT_Buffer,然后,在这个函数运行时*pBuffer,表示着*((u8*)TEXT_Buffer),对吧?



pBuffer这个在函数运行时,在自增,也就是,原数组所转换成的u8类型的指针,在自增的过程中指针所对应的内容,即*pBuffer,是在不停的改变,对吧,是这个意思吗?







正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 19:57:46 | 显示全部楼层
本帖最后由 ianhom 于 2016-1-28 23:31 编辑

一般数组元素的访问时通过下标,比如TEXT_Buffer[1]的值就为‘G’。因为数组名本身就是整个数组首个元素的地址,所以也可以使用指针的方式来访问数组中的每个元素,不过因为TEXT_Buffer[]是一个长度为11的数组,TEXT_Buffer数组名为一个常量,不能进行自加操作,所以这里需要将TEXT_Buffer的值(地址)给pBuffer这样的u8* 类型的指针变量(同时将const u8指针类型强制转换为u8的指针类型),这样在自加的时候就是偏移1个字节。

P.S:严格来说不会不停地改变,因为Good中有两个“o”
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 20:31:55 | 显示全部楼层
ianhom 发表于 2016-1-25 19:57
一般数组元素的访问时通过下标,比如TEXT_Buffer[1]的值就为‘G’。因为数组名本身就是整个数组首个元素的 ...

那你的意思就是说,(u8*)TEXT_Buffer实际上是数组中第一个元素所变换的指针的首地址?还是说,是整个数组的的指针啊?(u8*)TEXT_Buffer,这个指令是不是意味着,将数组中的所有元素都强制转化为u8类型的指针,即第0个数组元素转化为第0个指针,第1个数组元素转化为第1个指针,。。。。。第n个数组元素转化为第n个指针,然后*((u8*)TEXT_Buffer),这个指令意味着,读取,这个第0个指针对应的内容,也就是,原数组中的第0个元素,以此类推,是这个意思吧?
那也可以理解成,TEXT_Buffer这个表示各个数组元素即内容,(u8*)TEXT_Buffer,这个表示各个数组元素所强制转换成的各个u8类型指针,*((u8*)TEXT_Buffer)即*pBuffer,这个表示着,各个数组元素所强制转换成的各个u8类型指针的对应的各个内容,实际上就是原数组中的各个元素即内容,对吧?也就是可以理解成,元素→强制转换成的指针→调用各个指针的内容,即原数组中的各个元素,我这么说对吗?
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 21:25:55 | 显示全部楼层
本帖最后由 ianhom 于 2016-1-28 23:36 编辑
q546163199 发表于 2016-1-25 20:31
那你的意思就是说,(u8*)TEXT_Buffer实际上是数组中第一个元素所变换的指针的首地址?还是说,是整个数组 ...

那你的意思就是说,(u8*)TEXT_Buffer实际上是数组中第一个元素所变换的指针的首地址?还是说,是整个数组的的指针啊?
TEXT_Buffer是数组的函数名,其本身是个常量,其值为数组首元素的地址,而首个元素的类型是const u8类型。而(u8*)TEXT_Buffer则将这个指向const u8类型的地址作为一个指向u8类型的地址对待而已,仅仅是告诉编译器:“我将会把TEXT_Buffer这个指向const u8类型数组的地址作为一个指向u8类型数据的地址对待”。

(u8*)TEXT_Buffer,这个指令是不是意味着,将数组中的所有元素都强制转化为u8类型的指针,即第0个数组元素转化为第0个指针,第1个数组元素转化为第1个指针,。。。。。第n个数组元素转化为第n个指针,然后*((u8*)TEXT_Buffer),这个指令意味着,读取,这个第0个指针对应的内容,也就是,原数组中的第0个元素,以此类推,是这个意思吧?
强制类型转换仅仅会改变编译器对某个数据的看法或理解的角度,如上面回答的,(u8*)TEXT_Buffer这个操作仅仅是改变了编译器对“TEXT_Buffer”这个地址的看法,对数组中的数据是不会做看法的改变或作为指针对待。*((u8*)TEXT_Buffer)这样的操作只是在访问数组的第一个成员“!”,数组中的成员还是作为字符型数据对待。

那也可以理解成,TEXT_Buffer这个表示各个数组元素即内容,(u8*)TEXT_Buffer,这个表示各个数组元素所强制转换成的各个u8类型指针,*((u8*)TEXT_Buffer)即*pBuffer,这个表示着,各个数组元素所强制转换成的各个u8类型指针的对应的各个内容,实际上就是原数组中的各个元素即内容,对吧?也就是可以理解成,元素→强制转换成的指针→调用各个指针的内容,即原数组中的各个元素,我这么说对吗?
TEXT_Buffer仅仅能表示数组第一个成员的地址,(u8*)TEXT_Buffer仅仅能表示这个地址被作为指向u8类型的地址对待,原数组的各个元素不会作为指针对待。*pBuffer随着pBuffer的值不同可以代表着原数组中的各个成员,这些成员还是字符类型的数据,不是指针。
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 21:40:24 | 显示全部楼层
ianhom 发表于 2016-1-25 21:25
那你的意思就是说,(u8*)TEXT_Buffer实际上是数组中第一个元素所变换的指针的首地址?还是说,是整个数组 ...

(u8*)TEXT_Buffer,这句话实际上是将TEXT_Buffer变成了u8类型数据的指针变量的对吧?
而,pbuffer自增的话,加1即加一个字节,对应着数组中一个元素为一个字节,正好是,pbuffer加1,数组中对应元素变为下一个,对吧,谢谢您了,大神啊!!!
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 21:45:33 | 显示全部楼层
ianhom 发表于 2016-1-25 21:25
那你的意思就是说,(u8*)TEXT_Buffer实际上是数组中第一个元素所变换的指针的首地址?还是说,是整个数组 ...

(u8*)TEXT_Buffer这个操作仅仅是改变了编译器对“TEXT_Buffer”这个指针变量的看法,对数组中的数据是不会做看法的改变或作为指针对待。
*((u8*)TEXT_Buffer)这样的操作只是在访问数组的第一个成员“!”,数组中的成员还是作为字符型数据对待。
正是应为这两句话,*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);        这条语句在执行时,才不会影响到TEXT_Buffer数组中元素的变化,对吧?
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 21:49:23 | 显示全部楼层
ianhom 发表于 2016-1-25 21:25
那你的意思就是说,(u8*)TEXT_Buffer实际上是数组中第一个元素所变换的指针的首地址?还是说,是整个数组 ...

您看还有这个

u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{         
        u8 t;
        u32 temp=0;
        for(t=0;t<Len;t++)
        {
                temp<<=8;
                temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);                                             
        }
        return temp;                                                                                                   
}
AT24CXX,这个函数中,表示的从某一地址开始读取长度为LEN(2或4)的数据这是从大地址开始到小地址吗?即类似于地址顺序为3→2→1→0,是这样吗,我计算的是从大地址向小地址方向读取,我想知道为什么这么设计啊?为什么不从小地址向大地址方向读取啊?



void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
        while(NumToRead)
        {
                *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);        
                NumToRead--;
        }
}  

但是这个,读取的地址却是从小地址到大地址方向进行读取,我不能理解,求大神解释下,O(∩_∩)O哈!

回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 21:52:00 | 显示全部楼层
q546163199 发表于 2016-1-25 21:40
(u8*)TEXT_Buffer,这句话实际上是将TEXT_Buffer变成了u8类型数据的指针变量的对吧?
而,pbuffer自增的 ...

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

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 21:53:10 | 显示全部楼层
ianhom 发表于 2016-1-25 21:52
恩,可以这么理解

太感谢您了,谢谢您了
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 21:54:31 | 显示全部楼层
ianhom 发表于 2016-1-25 21:52
恩,可以这么理解

那我应该就可以认为,*TEXT_Buffer就是指数组中第一个内容吧?
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 21:56:01 | 显示全部楼层
q546163199 发表于 2016-1-25 21:45
(u8*)TEXT_Buffer这个操作仅仅是改变了编译器对“TEXT_Buffer”这个指针变量的看法,对数组中的数据是不 ...

*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++)这条语句貌似是在通过AT24CXX_ReadOneByte()函数,将ReadAddr地址及其后面的数据逐个字节的放到pBuffer所指向的区域,如果这里的pBuffer = (u8*)TEXT_Buffer的话,那原数组中的元素应该会发生变化
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 21:59:18 | 显示全部楼层
ianhom 发表于 2016-1-25 21:56
*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++)这条语句貌似是在通过AT24CXX_ReadOneByte()函数,将ReadAdd ...

这时的pBuffer变化了,变为datatemp这个了,       

u8 datatemp[SIZE];       
AT24CXX_Read(0,datatemp,SIZE);
应该可以认为,从地址0读取SIZE个数据,然后依次存储到datatemp这个数组中吧?
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 22:03:10 | 显示全部楼层
ianhom 发表于 2016-1-25 21:56
*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++)这条语句貌似是在通过AT24CXX_ReadOneByte()函数,将ReadAdd ...

您能留下联系方式吗?我的qq 546163199,我是个大新手,嘿嘿,
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 22:13:33 | 显示全部楼层
q546163199 发表于 2016-1-25 21:49
您看还有这个

u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)

这一点貌似和数据大小端有关系,第一段程序中要读的数据看起来是个小端模式,即高位字节在高地址,而低位字节在低地址上,假设int a = 0x11223344, 而a的地址假设为0x20000000,那在小端模式下,数据是如下存放的
     地址                 数据
0x20000000         0x44
0x20000001         0x33
0x20000002         0x22
0x20000003         0x11
所以按字节读取这个数据的时候,就需要先读3,然后移位,再读2,再移位。。。最后读0。

第二段程序如果结合你之前的程序,貌似是在读字符串,假设char a[] = "ABC"  ,数组的地址为0x200000000,那存放方式应该如下
      地址                   字符
0x20000000             ‘A’
0x20000001             ‘B’
0x20000002             ‘C’
0x20000003             ‘\0’
所以这里是按照小地址到大地址来读取的。

因为没有看到具体的上下文,所以以上仅仅是我的猜测,大小端的问题我也不是很熟,希望没有帮倒忙
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 22:24:57 | 显示全部楼层
本帖最后由 ianhom 于 2016-1-28 23:38 编辑
q546163199 发表于 2016-1-25 21:54
那我应该就可以认为,*TEXT_Buffer就是指数组中第一个内容吧?

可以这么理解,不过最好写成*((u8*)TEXT_Buffer),一来是告诉编译器你就是想把这个指针变量作为u8*类型来访问,二来也告诉读程序的人你的意图,这样的书写不会对储存空间和执行效率造成负担,但却是严谨的、良好的编程习惯。
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 22:26:15 | 显示全部楼层
ianhom 发表于 2016-1-25 22:13
这一点貌似和数据大小端有关系,第一段程序中要读的数据看起来是个小端模式,即高位字节在高地址,而低位 ...

我明白了
第一个函数,是读数据,高位数据在高位地址上,低位数据在低位地址上,所有,第一次读最高位数据之后,需要将其左移8位,用来存放我们所读取的次高位的数据,对吧?

第二个函数,就是在往数组里存放数据,第0个元素放地址x的内容,第1个元素放地址(x+1)的内容,以此类推,对吧?
太感谢您了,帮了我很大很大的忙!嘿嘿!
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 22:27:51 | 显示全部楼层
ianhom 发表于 2016-1-25 22:24
可以这么理解,不过我觉得这样使用会产生歧义,因为你如果使用*(TEXT_Buffer + 1)的话,并不是访问了第二 ...

恩恩,了解了,*TEXT_Buffer这个是在这个I2C例程里出现的,其实是*datatemp,这个
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 22:31:42 | 显示全部楼层
q546163199 发表于 2016-1-25 21:59
这时的pBuffer变化了,变为datatemp这个了,       

u8 datatemp;       

恩,从上面的函数看,是将地址为0~SIZE这段区域的数据,通过AT24CXX_ReadOneByte()函数依次赋值到datatemp[]数组中
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 22:34:36 | 显示全部楼层
q546163199 发表于 2016-1-25 22:26
我明白了
第一个函数,是读数据,高位数据在高位地址上,低位数据在低位地址上,所有,第一次读最高位数 ...

我是这么理解的,对于程序意图还是要你结合程序上下文来看哈,希望我没有帮倒忙,呵呵
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 22:37:37 | 显示全部楼层
ianhom 发表于 2016-1-25 22:34
我是这么理解的,对于程序意图还是要你结合程序上下文来看哈,希望我没有帮倒忙,呵呵

没有问题,我觉得你理解的对,厉害,我对这个C语言,以前学的都忘光了,我现在就是先会用,到时候真要自己做板子的话,我感觉这种程序什么,改改就能移植过去吧?
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 22:38:00 | 显示全部楼层
q546163199 发表于 2016-1-25 22:27
恩恩,了解了,*TEXT_Buffer这个是在这个I2C例程里出现的,其实是*datatemp,这个

说来惭愧,我买了mini板后,连基本例程试验还没有做全。。。。。stm32初学,现在还在c语言学习阶段。。。。。。。
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 22:38:17 | 显示全部楼层
ianhom 发表于 2016-1-25 22:31
恩,从上面的函数看,是将地址为0~SIZE这段区域的数据,通过AT24CXX_ReadOneByte()函数依次赋值到datatem ...

ok,好的,谢谢您了,希望我理解的对吧,哈哈,太苦恼了,烦了一天了
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 22:39:39 | 显示全部楼层
ianhom 发表于 2016-1-25 22:38
说来惭愧,我买了mini板后,连基本例程试验还没有做全。。。。。stm32初学,现在还在c语言学习阶段。。。 ...

我买的是探索者的,那你已经比我厉害多了,我看了将近三个月了吧,才看到I2C,这个效率,我也是醉了,我现在大四了,诶,时间是不允许我再去复习了,只能硬挺了
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 22:39:50 | 显示全部楼层
q546163199 发表于 2016-1-25 22:37
没有问题,我觉得你理解的对,厉害,我对这个C语言,以前学的都忘光了,我现在就是先会用,到时候真要自 ...

程序理解透了以后,移植起来没有问题的
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 22:41:13 | 显示全部楼层
ianhom 发表于 2016-1-25 22:39
程序理解透了以后,移植起来没有问题的

恩恩,我觉得也是这样的,最多是改改引脚什么的,大体上的外设初始化,应该都是相同的
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-25 22:42:09 | 显示全部楼层
q546163199 发表于 2016-1-25 22:39
我买的是探索者的,那你已经比我厉害多了,我看了将近三个月了吧,才看到I2C,这个效率,我也是醉了,我 ...

年轻有为,比我强多了
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-25 22:42:36 | 显示全部楼层
ianhom 发表于 2016-1-25 22:42
年轻有为,比我强多了

大神谦虚啊,我以后还得多多请教您了,O(∩_∩)O哈哈~
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-26 02:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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