吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 437|回复: 5
收起左侧

[求助] 对于s3c2440_lcd_test.c中p = (unsigned short *)fb_base;的不解

[复制链接]
silverviolet 发表于 2023-11-6 14:02
       int fb_base的定义追溯到lcd.h中
/* framebuffer的地址 */
unsigned int fb_base;

      在lcd_test.c中对于fb_base的定义如下
void lcd_test(void)
{
        unsigned int fb_base;
        int xres, yres, bpp;
        int x, y;
        unsigned short *p;
        unsigned int *p2;
        ......;
     /* 获得LCD的参数: fb_base, xres, yres, bpp */
get_lcd_params(&fb_base, &xres, &yres, &bpp);

/* 往framebuffer中写数据 */
if (bpp == 16)
{
        /* 让LCD输出整屏的红色 */

        /* 565: 0xf800 */

        p = (unsigned short *)fb_base;
        for (x = 0; x < xres; x++)
                for (y = 0; y < yres; y++)
                        *p++ = 0xf800;
       ......;
}
       疑惑于(unsigned short*)fb_base是个指针,fb_base通过类型转换把unsigned int转换成 unsigned short赋值给p?
      
       当p的类型是float*,int*,double*时候,fb_base的类型可以是short,反之,当p的类型是short*,fb_base的类型不能是float,double,(int可以)
这是何解?
       #include<iostream>
using namespace std;
float s = 1000.123;
short * p =NULL ;


int main()
{
       
       
        p = (short *)s;
        cout << "s =" << s << endl;
        cout << "&s =" << &s << endl;
        cout << "p =" << p << endl;
        cout << "&p =" << &p << endl;
       
        return 0;
}
附图如下

微信图片_20231106134707.png
微信图片_20231106140121.png

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
为之奈何? + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

imcuer 发表于 2023-11-6 14:16
本帖最后由 imcuer 于 2023-11-6 14:26 编辑

(unsigned short *)fb_base; 就是将 fb_base 地址中存放的内容看做是 unsigned short 类型,当然里面存放的可能不是真正的 unsigned short 类型,这时用强类型转换 (unsigned short*) 明确指示一下,即将 fb_base中的内容看做是 unsigned short 内容了,之后就可以将其赋值给其它相应类型的变量了,这样就可以避免了编译器的报错,编译器允许你在不同类型之间相互赋值,但要求你要明确声明一下,编译器只对语法负责,不对结果负责。因为只有你能确认内存中的数值是不是可转化的。
 楼主| silverviolet 发表于 2023-11-6 20:11
imcuer 发表于 2023-11-6 14:16
(unsigned short *)fb_base; 就是将 fb_base 地址中存放的内容看做是 unsigned short 类型,当然里面存放 ...

      首先谢谢您的答复,我看过有种解释跟您的很像,
      如下:
      代码中直接访问寄存器: *(volatile unsigned short *)的含义
*(volatile unsigned short *)0x20000000 的意义
volatile 表示 禁止编译器优化.

unsigned short * 的意思是定义一个2个字节的地址指针, 连起来就是在0x20000000地址位置上输出一个2个字节长的数据。

( unsigned short * )是声明了一个 指针,
指针本身就是数值,

unsigned short *p = ( unsigned short * )0x20000000;
*p = 0; 与 *( unsigned short * )0x2000000 = 0;是一样的。

(volatile unsigned short *)0x20000000=XXX -->0x20000000被定义成一个指针,指向xxx地址。

*(volatile unsigned short *)0x20000000=XXX -->0x20000000指向的地址的值是xxx。
          当p的类型是float*,int*,double*时候,fb_base的类型可以是short,反之,当p的类型是short*,fb_base的类型不能是float,double,(int可以),等号右边类型只能比左边类型的字节长度要长才行
这是何解?
imcuer 发表于 2023-11-7 08:55
当p的类型是short*时, 由于short类型占两个字节空间, float类型占四个字节空间,当用 short* 取 float 内容时,只能取出float四个字节中的两个字节, 所以编译器提示无法将 float 转成 short, 反之如果 当p的类型是float*,int*,double*时候, 由于float 占4个字节,int 占4个字节,double占8个字节,那么*p可以完整的取出 short 的4个字节,不存在截断的问题,但此时要注意越界的问题,例如用 double 型指针取 short 类型数值时。
yes2 发表于 2023-11-7 09:14
本帖最后由 yes2 于 2023-11-7 09:19 编辑
imcuer 发表于 2023-11-7 08:55
当p的类型是short*时, 由于short类型占两个字节空间, float类型占四个字节空间,当用 short* 取 float 内 ...

我不太认可你的回答。楼主转换失败是因为float无法直接转换为指针,编译器一般不管这事,实在是它觉得这转换太不符合逻辑了所以报个错。
改成这样就能通过编译:p=(short*)(int)s;
或者这样更精确:p = (short*)*(int*)&s;
但是这样大概率会崩,因为一个浮点数的二进制数值,强制作为指针去访问的话,结果可以说是未定义的。

对于强制类型转换, 开发者最好能搞清楚原理,以及在实际编码中明白自己在做什么。
比如简单的,楼主的1000.123,int n = (int)s; 这样会转出一个n=1000;
如果是指针类型的就更要做到心里有数,比如const char* str = "123"; str中存储的是字符串,也可以当做整数来读取int* pn = (int*)str; 那么*pn就是0x333231。

楼主的问题,其实就是整数强制转换为指针成功但是浮点转换为指针没成功。这个可能是编译器最后的防线了,开发者如果清楚自己在做什么,那么就可以像我开头写的那样绕过去,如果绕不过去,那大概率是不清楚自己在做什么的,容易crash。
建议多使用调试功能,调试功能里可以查看内存,涉及内存和数组,指针强制转换之类的,除了语法学会之外,配合调试查看内存可以更快进步
 楼主| silverviolet 发表于 2023-11-8 11:35
yes2 发表于 2023-11-7 09:14
我不太认可你的回答。楼主转换失败是因为float无法直接转换为指针,编译器一般不管这事,实在是它觉得这 ...

        谢谢您的留言,我懂了,指针类强制类型转化避开float,double
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 17:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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