以下C运算符如何组合
How does the following C operators combined
对于 EFR32FG14P231F256M32,我有以下 C 运算符组合。显示的描述 bellow.I 无法将描述与代码匹配。
->
是一个指针。我们两边都有指路?
|
是按位或
.DOUT
我认为意味着从下面的 P[gpioPortC]
单元格中获取 DOUT
成员,
但正在重新分级 | (1 << 5);我无法理解。
单行中这样的 C 运算符组合的逻辑含义是什么?
以下代码将端口 C 的引脚 5 配置为带上拉和滤波器的数字输入。来自 GPIO_PC_MODEL 的 MODE5 位域
寄存器必须设置为0b0011,GPIO_PC_DOUT寄存器中对应的位也必须设置为1来确定上拉
方向。可以使用 emlib 中可用的函数或直接写入寄存器来配置引脚:
GPIO->P[gpioPortC ].DOUT = GPIO->P[gpioPortC ].DOUT | (1 << 5); //Input enabled with pull up and filter
GPIO->P[gpioPortC ].MODEL = (GPIO->P[gpioPortC ].MODEL & ~_GPIO_P_MODEL_MODE5_MASK) |
GPIO_P_MODEL_MODE5_INPUTPULLFILTER;
<<运算符表示"shift bits left",其作用如下:
a << b
将 a、b 位向左移动。
直接回答你的问题,1 << 5 将 0x01 中的位向左移动 5 次,结果是 0x20,即十进制表示法中的 32。这具有将数字乘以 2 n 次的效果(在您的情况下为 n=5)。结果值与 DOUT 中的值进行或运算,然后存储在 DOUT 本身中。
编辑:
回答 OP 在评论中添加的问题 -
您代码中的赋值与此类似:x = x + 5
。
->
运算符对于 (*obj).field
是 shorthand。代码中的第一行指示如下:
- 取
GPIO->P[gpioPortC].DOUT
内的值并与 0x10
进行或运算。
- 将结果赋给
GPIO->P[gpioPortC].DOUT
。
第二行执行了一个非常相似的操作,只是不是执行按位或并将其存储在同一字段中,而是执行该字段的按位与与某个预定义值的取反形式,然后执行一个结果与另一个预定义值的按位或,然后将其存储在该字段中。
重要的是要理解,简单地在对象上使用 ->
运算符除了允许您访问存储在该对象中的字段(它们本身可能是指向内存中其他位置的指针,或原始变量)。
1 << 5
是具有二进制值 0b100000
的常量表达式。您可以简单地将其替换为文字常量值 0x20 或 32,但是该表达式的目的是创建一个设置了位 5 的 位掩码 。
这样表示是因为:
- 它记录意图而无需写评论。它是自记录代码 - 它对 reader "this is a mask for bit 5",
说
- 在编码的时候,让编译器计算5位掩码的常量值不容易出错。
所以:
x = x | ( 1 << 5) ;
设置变量的第 5 位(或在本例中 register)x
。关于你的,也可以表示为:
x |= (1 <<5) ;
关于你的次要问题:
->
is a pointer. We have pointing directions on both sides?
我不清楚你在问什么,->
但不是指针;它是 结构取消引用 运算符;它的左手操作数是一个指针,它的右手操作符是结构的成员,左手是一个指针 to (它可能是也可能不是指针。
在你问之前,你的片段的第二行有 形式:
x = x & ~mask ;
将 x
中所有在 mask
中为 1 的位设置为零。它是前一个成语的反转:
x &= ~mask ; // Clear mask bits
x &= mask ; // Set mask pits
在您的特定示例中,您有一个更复杂的表达式:
GPIO->P[gpioPortC].DOUT | (1 << 5)
这里需要理解operator precedence的概念。 ->
优先于 |
,因此首先计算 GPIO->P[gpioPortC].DOUT
子表达式,以便 | (1 << 5);
应用于引用结构的 DOUT
成员。请注意,[]
也是一个运算符(优先级高于 ->
。因此在一般形式中:
x | y ;
...
x = GPIO->P[gpioPortC].DOUT
y = (1 << 5)
对于 EFR32FG14P231F256M32,我有以下 C 运算符组合。显示的描述 bellow.I 无法将描述与代码匹配。
->
是一个指针。我们两边都有指路?|
是按位或.DOUT
我认为意味着从下面的P[gpioPortC]
单元格中获取DOUT
成员,
但正在重新分级 | (1 << 5);我无法理解。
单行中这样的 C 运算符组合的逻辑含义是什么?
以下代码将端口 C 的引脚 5 配置为带上拉和滤波器的数字输入。来自 GPIO_PC_MODEL 的 MODE5 位域 寄存器必须设置为0b0011,GPIO_PC_DOUT寄存器中对应的位也必须设置为1来确定上拉 方向。可以使用 emlib 中可用的函数或直接写入寄存器来配置引脚:
GPIO->P[gpioPortC ].DOUT = GPIO->P[gpioPortC ].DOUT | (1 << 5); //Input enabled with pull up and filter
GPIO->P[gpioPortC ].MODEL = (GPIO->P[gpioPortC ].MODEL & ~_GPIO_P_MODEL_MODE5_MASK) |
GPIO_P_MODEL_MODE5_INPUTPULLFILTER;
<<运算符表示"shift bits left",其作用如下:
a << b
将 a、b 位向左移动。 直接回答你的问题,1 << 5 将 0x01 中的位向左移动 5 次,结果是 0x20,即十进制表示法中的 32。这具有将数字乘以 2 n 次的效果(在您的情况下为 n=5)。结果值与 DOUT 中的值进行或运算,然后存储在 DOUT 本身中。
编辑: 回答 OP 在评论中添加的问题 -
您代码中的赋值与此类似:x = x + 5
。
->
运算符对于 (*obj).field
是 shorthand。代码中的第一行指示如下:
- 取
GPIO->P[gpioPortC].DOUT
内的值并与0x10
进行或运算。 - 将结果赋给
GPIO->P[gpioPortC].DOUT
。
第二行执行了一个非常相似的操作,只是不是执行按位或并将其存储在同一字段中,而是执行该字段的按位与与某个预定义值的取反形式,然后执行一个结果与另一个预定义值的按位或,然后将其存储在该字段中。
重要的是要理解,简单地在对象上使用 ->
运算符除了允许您访问存储在该对象中的字段(它们本身可能是指向内存中其他位置的指针,或原始变量)。
1 << 5
是具有二进制值 0b100000
的常量表达式。您可以简单地将其替换为文字常量值 0x20 或 32,但是该表达式的目的是创建一个设置了位 5 的 位掩码 。
这样表示是因为:
- 它记录意图而无需写评论。它是自记录代码 - 它对 reader "this is a mask for bit 5", 说
- 在编码的时候,让编译器计算5位掩码的常量值不容易出错。
所以:
x = x | ( 1 << 5) ;
设置变量的第 5 位(或在本例中 register)x
。关于你的
x |= (1 <<5) ;
关于你的次要问题:
->
is a pointer. We have pointing directions on both sides?
我不清楚你在问什么,->
但不是指针;它是 结构取消引用 运算符;它的左手操作数是一个指针,它的右手操作符是结构的成员,左手是一个指针 to (它可能是也可能不是指针。
在你问之前,你的片段的第二行有 形式:
x = x & ~mask ;
将 x
中所有在 mask
中为 1 的位设置为零。它是前一个成语的反转:
x &= ~mask ; // Clear mask bits
x &= mask ; // Set mask pits
在您的特定示例中,您有一个更复杂的表达式:
GPIO->P[gpioPortC].DOUT | (1 << 5)
这里需要理解operator precedence的概念。 ->
优先于 |
,因此首先计算 GPIO->P[gpioPortC].DOUT
子表达式,以便 | (1 << 5);
应用于引用结构的 DOUT
成员。请注意,[]
也是一个运算符(优先级高于 ->
。因此在一般形式中:
x | y ;
...
x = GPIO->P[gpioPortC].DOUT
y = (1 << 5)