搜索
bottom↓
回复: 40

请教大神,*(u16 *)中右边的*号是什么意思?

[复制链接]

出0入0汤圆

发表于 2011-12-29 18:29:22 | 显示全部楼层 |阅读模式
在STM32  FSMC配置里看到这样一句

*(u16 *) (Bank1_SRAM3_ADDR + WriteAddr) = *pBuffer++;

请问*(u16 *)中,u16后面的*号是什么意思?

网上找了好久,没找到相关资料

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2011-12-29 18:34:06 | 显示全部楼层
u16 * a;//这个也没见过?

出0入0汤圆

发表于 2011-12-29 18:43:54 | 显示全部楼层
这是表情吖
*(^_^)*

出0入0汤圆

 楼主| 发表于 2011-12-29 18:44:57 | 显示全部楼层
回复【1楼】AIDN  
u16 * a;//这个也没见过?
-----------------------------------------------------------------------

那*(u16 *)中的左右两个*号分别是什么意思呢?麻烦您讲一下好吗?

出0入0汤圆

 楼主| 发表于 2011-12-29 18:46:50 | 显示全部楼层
回复【2楼】catx  猫杀吖
这是表情吖
*(^_^)*
-----------------------------------------------------------------------

你见过*(^_^*)这样的表情吗?

出0入0汤圆

发表于 2011-12-29 18:48:05 | 显示全部楼层
回复【4楼】Crazy Rain  
-----------------------------------------------------------------------

要是有人的脸长得不对称也不能歧视他吖

出0入0汤圆

发表于 2011-12-29 18:48:27 | 显示全部楼层
好吧
其实是先强制转型
然后取值

出0入0汤圆

发表于 2011-12-29 18:51:05 | 显示全部楼层
*p 见过吗?
(u16 *)p 见过吗?
*((u16 *)p)见过吗?
*(u16 *)p 该知道了吧

出0入0汤圆

发表于 2011-12-29 18:51:31 | 显示全部楼层
关于表情
*(^_^*)和(*^_^)*

出0入0汤圆

 楼主| 发表于 2011-12-29 18:55:10 | 显示全部楼层
回复【8楼】xivisi  LiYong
*p 见过吗?
(u16 *)p 见过吗?
*((u16 *)p)见过吗?
*(u16 *)p 该知道了吧
-----------------------------------------------------------------------

(u16 *)p 。。这个真没见过。。

u16 *p跟(u16 *)p有什么区别吗?

出0入8汤圆

发表于 2011-12-29 18:55:14 | 显示全部楼层
其实是将一个数值转换为u16的指针,然后就是对指针指向的地址赋值

出0入0汤圆

 楼主| 发表于 2011-12-29 19:01:31 | 显示全部楼层
回复【11楼】lindabell  欧海
-----------------------------------------------------------------------

非常感谢!


回复【13楼】myqiang1990  小松鼠
回复【11楼】lindabell 欧海
-----------------------------------------------------------------------
就这个、、、楼主c语言不过关啊。。。

-----------------------------------------------------------------------
这个秘密又被你发现了

出0入0汤圆

发表于 2011-12-29 19:11:23 | 显示全部楼层
回复【14楼】Crazy Rain
-----------------------------------------------------------------------

举一个浅的例子吧...
u16 a;
u16 *ptr=&a;//这句话就是(u16 *) (Bank1_SRAM3_ADDR + WriteAddr),那么&a的值就是(Bank1_SRAM3_ADDR + WriteAddr)把它付给ptr后,ptr就变成了(u16 *) (Bank1_SRAM3_ADDR + WriteAddr)...-------------(1)

那么我们怎么赋值给p所指向的地址啊?不可能是ptr=*pBuffer++; 是吗??你见过有这样用的吗?不是大错特错吗?
正确的应该是*ptr=*pBuffer++;你吧(1)替换进来不就是你那个句话吗?

出0入0汤圆

 楼主| 发表于 2011-12-29 19:15:58 | 显示全部楼层
回复【15楼】myqiang1990  小松鼠
-----------------------------------------------------------------------

明白了,谢谢~

出0入0汤圆

发表于 2011-12-29 21:21:46 | 显示全部楼层
楼主明白了,我就不说了。指针的用法。
估计这一个用法会让楼主花时间思考
*( ( void(*)())0x0000 ) )()
就是跳到0地址开始执行

出0入0汤圆

发表于 2011-12-29 22:52:28 | 显示全部楼层
楼上*( ( void(*)())0x0000 ) )() 在KEILV3中编译不过,改为(*(((void(*)())0x0000 )))() ;或(((void(*)())0x0000 ))();编译OK执行OK; 刚毕业的时候研究过这个。现在想想为什么(*p)()跟p()执行结果一样?我现在理解函数名就是地址。*p的内容是地址。p是指向函数的指针。所以结果一样?

出0入0汤圆

 楼主| 发表于 2011-12-29 23:21:45 | 显示全部楼层
楼上两位大虾的语句表示完全看不懂。。。。

出0入0汤圆

发表于 2011-12-30 00:52:03 | 显示全部楼层
学习下。新手

出0入0汤圆

发表于 2011-12-30 01:10:26 | 显示全部楼层
(((void(*)())0x0000 ))() 是函数指针问题,比起变量指针,是难了点。相信楼主会逐渐进阶上去。我也曾经害怕过指针,更恐惧过函数指针,实践中闯过来就好多了。建议读一下这本书:
点击此处下载 ourdev_708906CMJEEO.pdf(文件大小:898K) (原文件名:ourdev_466338_C语言深度解剖.pdf)

出0入0汤圆

发表于 2011-12-30 08:34:33 | 显示全部楼层
回复【3楼】Crazy Rain  
-----------------------------------------------------------------------

*(u16*)p先不管括号就成了*p再不管*就成了p
(Bank1_SRAM3_ADDR   WriteAddr)就是这个p,在这里p是个地址就是指针(注意储存这个地址的地方才是p),*p就是要对这个地址的值操作(注意是p里面的值作为地址,对这个地址里的值进行赋值运算等操作)

再看看(u16*)的()是强制转换,u16*是一种指针类型,(u16*)就是把指针强制转换成u16*

出0入0汤圆

发表于 2011-12-30 13:26:50 | 显示全部楼层
回复【18楼】xnliuxiwen
-----------------------------------------------------------------------
是的,函数名就是地址。C教材(谭浩强写的那本)上有说的,函数地址调用函数时,加不加前面那一个星号都可以,但是要注意函数指针和*、()的结合优先级,如(*pFun)()和*pFun()是不同的
void Test()
{
    ...
}

int main(void)
{
    void (*pFun)() = Test;

    (*pFun)();                  /* (*pFun)()和pFun()作用一样,都是实现Test()函数调用   */
     pFun();
}

出0入0汤圆

发表于 2011-12-30 13:29:13 | 显示全部楼层
回复【18楼】xnliuxiwen
-----------------------------------------------------------------------

笔误 *( ( void(*)())0x0000 ) )();左边少加了一个左括号,
    (*( ( void(*)())0x0000 ) )();
  {加上左括号}

出0入0汤圆

发表于 2011-12-30 13:56:44 | 显示全部楼层
这一段代码有意思(51单片机平台)
int main(void)
{
    unsigned char code Reset[]={0xE4,0xC0,0xE0,0xC0,0xE0,0x32};   /* 复位代码,属于机器码                  */

    (*((void (*)())(Reset)))();                                   /* 将Reset数组当函数调用                 */
}


(原文件名:s.jpg)

也就是数组中的数据是四条汇编指令
    CLR A
    PUSH ACC
    PUSH ACC
    RETI
的机器码,这样(*((void (*)())(Reset)))()就执行了(一般只对普林斯顿结构的MCU、PC、其他处理器有用—数据空间和程序空间地址统一编码)
    CLR A
    PUSH ACC
    PUSH ACC
    RETI
这样的操作。想想可不可做病毒,或者在外部存储器中(外部EEPROM、SD卡、U盘)存储一个文件,该文件就是特定程序的机器码,把这样的存储器插入到设备中时,处理器/单片机读入数据到内部SRAM,之后运行这个读入的程序

出0入0汤圆

发表于 2011-12-30 14:01:26 | 显示全部楼层
回复【25楼】XL_J  
-----------------------------------------------------------------------

类似的技术用得很多
而且不限于嵌入式
比如软件反破_解的花指令
虚拟机字节码Just In Time优化的ASM emitter

而且其实你程序存储在媒体上
本身就是以这种形式
用Linux就知道
同样的文件
设置成可执行属性才会当做程序执行
不然就是数据。。。。

出0入0汤圆

发表于 2011-12-30 14:08:00 | 显示全部楼层
回复【26楼】catx 猫杀吖
-----------------------------------------------------------------------

这样,明白。PC机上的不太懂,高端的嵌入式Linux方面也不会,我只会一点点低端嵌入式产品开发,呵呵

出0入0汤圆

发表于 2011-12-30 14:21:22 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-12-30 21:08:04 | 显示全部楼层
回复【25楼】XL_J

这一段代码有意思(51单片机平台)
int main(void)
{
    unsigned char code reset[]={0xe4,0xc0,0xe0,0xc0,0xe0,0x32};   /* 复位代码,属于机器码                  */
    (*((void (*)())(reset)))();                                   /* 将reset数组当函数调用                 */
}


(原文件名:s.jpg)
<center><a class=tt16 onclick="fnquickimagequote(this,'files_49/ourdev_709002xumw8j.jpg','原文......
-----------------------------------------------------------------------

你这个也学习过嘿嘿。挺实用的嘛。

出0入0汤圆

发表于 2011-12-31 15:34:02 | 显示全部楼层
由*(^_^*)引发的血案。。。。。

出0入0汤圆

发表于 2012-1-6 11:59:13 | 显示全部楼层
血案

出0入0汤圆

发表于 2012-1-6 19:49:21 | 显示全部楼层
右边那个*表示将此变量强制转换为u16的指针,左边那个*表示取这个指针的值。

出0入0汤圆

发表于 2012-1-6 21:27:17 | 显示全部楼层
*(u16 *) (Bank1_SRAM3_ADDR + WriteAddr) = *pBuffer++;

Bank1_SRAM3_ADDR + WriteAddr 单片机只能识别为一个十六进制数值,具体是数据还是地址,它并不能自动区分.

(u16 *) (Bank1_SRAM3_ADDR + WriteAddr) 对此数据进行强制转换,表明此数值为一个无符号的短整型地址指针值.

*(u16 *) (Bank1_SRAM3_ADDR + WriteAddr) 则是获取指针所指向地址处的内容.

楼主这句话的意思是将指针变量pBuffer所指向的数值送至 *(u16 *) (Bank1_SRAM3_ADDR + WriteAddr) 地址处,然后自增 1.

出0入0汤圆

发表于 2012-1-7 09:02:48 | 显示全部楼层
对指针指向的地址取值操作并做强制转换

出0入0汤圆

发表于 2015-9-24 16:29:18 | 显示全部楼层
这个得好好学习一下!!!

出0入0汤圆

发表于 2015-9-24 16:45:31 | 显示全部楼层
以前看了指针的操作后, 就和最早在学单片机汇编时的寄存器间接寻址联系到一起了

出0入0汤圆

发表于 2015-9-24 16:56:57 | 显示全部楼层
这些真的要好好慢慢的理解

出0入0汤圆

发表于 2019-6-26 18:02:23 | 显示全部楼层
强制转换

出20入70汤圆

发表于 2019-6-26 18:11:11 | 显示全部楼层
这坟挖的!!!!

出0入0汤圆

发表于 2019-7-2 07:18:11 | 显示全部楼层
  强制转换为 u16的指针
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 06:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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