【问题标题】:Can someone please explain me this Pointer usage?有人可以解释一下这个指针的用法吗?
【发布时间】:2014-11-01 20:58:20
【问题描述】:

我正在学习如何在 Linux 下为 ARM A9 编写代码。现在我访问一些外围设备,如 LEDS。我的代码实际上正在运行,但部分基于教程。 我唯一不明白的部分是:

  void *virtual_base;
  void *led_addr;
  void *sw_addr;
  int fd;
  int switches;
  switches=*(uint32_t *)sw_addr;

`

我不明白的部分是为什么我必须写 *(uint32_t *)sw_addr;

*sw_addr 表示它是一个变量,它指向一个特定的地址。在我的例子中,它指向特定的外围寄存器。从这个地址读取将读取我板上开关的状态。 但是什么

*(uint32_t *)sw_addr 方法?你如何解释它? 为什么我就是不能写 switches= sw_addr?

如你所见,我有点困惑。

【问题讨论】:

  • (uint32_t *) 这是一个演员表,* 这是取消引用您刚刚转换的对象。
  • sw_addr 被定义为void *(指针)。 (uint32_t *) 这是一个演员表,现在说 void * 现在是指向 uint32_t 的指针。最左边的* 然后表示将(uint32_t *)sw_addr 指向的整数存储在开关中。需要注意的一点是,将其更改为 *(int *)sw_addr 或将 switches 更改为使用 uint32_t switches 定义为 uint32_t 可能是一个好主意。这使类型保持一致。
  • 所以最好将 sw_addr 定义为 uint32_t 而不是 void?
  • @user3597998 并非总是如此。这取决于寄存器的长度。您的代码正在读取寄存器内容并将其存储在switches 中。我认为最好的方法是定义指向与相应长度匹配的寄存器的指针。
  • 不管转换/重新解释如何进行,因为 sw_addr 从未初始化,所以这段代码很可能会中断......

标签: c linux


【解决方案1】:

sw_addr 是一个void 指针。 void 指针不能被取消引用,因为 void 是无类型类型,即没有像 void a; 这样的东西作为变量声明。因此,指针在被取消引用之前被转换为uint32_t*。 sw_addr 地址处的值现在被解释为 `uint32_t,当它被取消引用时。

编辑:我应该提到代码中的特定操作可能不安全,因为您将结果分配给一个 int(它是有符号的,而 uint32_t 中的 u 代表无符号)。 int 可能无法表示存储在 uint32_t 中的数字,首先是因为 unsigned ints 可以存储更大的数字,但也可能是因为 int 不能保证为 32 位大。

【讨论】:

    【解决方案2】:

    让我们把它分解成几个步骤:

    1. sw_addr 是一个变量。变量的值为X
    2. 在内存中,地址 X 处有一些 32 位(4 字节)值,您希望将其读入变量“switches”。
    3. *sw_addr 表示“地址 X 处的值”,表示我们要读入“开关”的值。
    4. 由于sw_addrvoid * 类型,我们不能写switches = *sw_addr;,因为编译器不知道您要读取的数据的大小。也许您试图只读取一个字节,也许两个字节,也许四个?
    5. 转换(uint32_t *)sw_addr 告诉编译器查看sw_addr,就好像它是指向uint32_t 的指针,这意味着指向无符号32 位值的指针。
    6. *((uint32_t *)sw_addr); 语句(为了清楚起见,我添加了另一对括号,但这并不重要)表示我们的 (uint32_t *)sw_addr 指针指向的值,即地址 X 处的 4 字节无符号值。
    7. 在转换到位后,我们可以写入switches=*(uint32_t *)sw_addr;,很明显我们打算将地址X 的4 个字节读入switches

    或者,我们可以编写以下内容:

    uint32_t *sw_addr;
    int switches;
    
    switches=*sw_addr;
    

    【讨论】:

      【解决方案3】:

      “傻瓜”答案:

      *(uint32_t *)sw_addr means?
      

      这意味着,从sw_addr 指向的位置给我uint32_t 的数据(32 位)。

      How do you interpret it?
      

      void *sw_addr 指向未知大小的东西,它是void pointer。将其转换为uint32_t 指针告诉我们它指向32bit unsigned integer。然后当我们想要数据时,我们得到32 bits(假设所有的转换都是正确的并且可以进行)。

      Why I just cant write switches= sw_addr?
      

      假设你的意思是switches = *sw_addr,那是因为它就像在说:给我来自指针sw_addr的未知数量的数据(我们也不知道它指向的类型)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-09
        • 1970-01-01
        • 2017-09-02
        • 2011-07-12
        • 1970-01-01
        相关资源
        最近更新 更多