有人可以解释一下这个Pointer用法吗?

时间:2014-11-01 20:58:21

标签: c linux

我正在学习如何在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

我有点困惑,你可以看到。

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

让我们分解为步骤:

  1. sw_addr是一个变量。变量的值为 X
  2. 在内存中,地址X处有一些32位(4字节)值,您希望将其读入变量“switch”。
  3. *sw_addr表示“地址X的值”,表示我们想要读入“开关”的值。
  4. 由于sw_addr的类型为void *,因此我们无法编写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
  8. 或者,我们可以写下以下内容:

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

答案 2 :(得分:0)

" for dummies"回答:

*(uint32_t *)sw_addr means?

这意味着,从uint32_t指向的位置给我sw_addr个数据(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向我提供未知数量的数据(我们不知道它的类型)我也指着。