#include "lm4f120h5qr.h"
#define LED_RED (1u<<1)
#define LED_BLUE (1u<<2)
#define LED_GREEN (1u<<3)
GPIO_PORTF_DATA_R |= LED_RED; // line1
*((unsigned long volatile *)(0x40025000 +(LED_RED << 2)))=LED_RED;//line2
*(GPIO_PORTF_DATA_BITS_R + LED_RED)=LED_RED; //line3
GPIO_PORTF_DATA_BITS_R[LED_RED]=LED_RED; //line3
我正在关注互联网课程,这是使用“数组和指针算术”的一个例子。但我无法理解使用“指针算法”来修改特定位的概念。
我可以理解“line1”,它修改了一个位,而没有改变GPIO_PORTF_DATA_R指向的位置中的任何其他位,因此它打开了RED LED(如果我在这里弄错了,请纠正我)。
我可以理解为什么我们在“line2”中移位2位,因为我们忽略了2个最后的位,并且“line2”和“line3”共享相同的概念,他们在Disassembly中执行相同的指令。
我的第一个问题是*(GPIO_PORTF_DATA_BITS_R + LED_RED)究竟指向哪里?以及*(GPIO_PORTF_DATA_BITS_R + LED_RED)= LED_RED如何工作?
第二个问题是为什么我们不再需要在“line3”中移位2位。他们说它是自动完成的,但有人可以解释背后的原因吗?
谢谢。
我不确定上下文是什么,但我可以回答你的两个问题:
GPIO_PORTF_DATA_BITS_R
是一个数组,*(GPIO_PORTF_DATA_BITS_R + LED_RED)=LED_RED
将无符号int值LED_RED
赋值给数组中的LED_RED
th位置。再次不确定为什么要将LED_RED
分配给数组中的那个位置,但这取决于你。GPIO_PORTF_DATA_BITS_R
是一个4字节值的数组(我用Google搜索并看到它是32位)。内存是字节寻址的,因此如果要转到数组中的LED_RED
th位置,可以将LED_RED * 4
添加到数组起始处的内存地址中。但是,C中的指针算法知道*GPIO_PORTF_DATA_BITS_R
的大小,因此自动在第3行中进行4次乘法运算。编辑:不是将LED_RED
2个字节向左移动,更简洁的计算内存地址偏移的方法是LED_RED * sizeof(*GPIO_PORTF_DATA_BITS_R)
(或者如果你只是设置一个数组值那么就做你在第3行做的事情)。