C语言声明优先级(precedence rule)

以下文字摘自expert c programming

A    Declarations are read by starting with the name and then reading in precedence order.


B The precedence, from high to low, is:
B.1 parentheses grouping together parts of a declaration
B.2 the postfix operators:
parentheses () indicating a function, and
square brackets [] indicating an array.
B.3 the prefix operator: the asterisk denoting "pointer to".


C      If a const and/or volatile keyword is next to a type specifier (e.g. int, long, etc.) it

applies to the type specifier. Otherwise the const and/or volatile keyword applies to the

pointer asterisk on its immediate left.

个人觉得这里next to理解为adjacent to而不是after,中文版的译者翻译成的是after的意思。

相当于说const,volatile与类型说明符刚好挨着,那么它修饰类型说明符。否则它与左边的*(星号)左结合,修饰左边的星号


const int * grape


const 修饰int,代表常量,grape为指向const int类型的指针


int const * grape

const修饰int,const int与int const等价


int* const grape_jelly

这里const修饰的是*,意味着grape_jelly是个指针常量

不能修改grape_jelly使它指向其他的对象



static STATUS _fptIpRule2ConfigObj(TPCONFIG_SET_INPUT *stInput, char *tblKey, FPT_IP_RULE *ipRule, INT64 score) { PFM_IF_FAIL_RET_VAL(tpConfig_objAddKeyScoreForSet(stInput, TPCONFIG_INIT_ENTRY, tblKey, score), ERR_BAD_PARAM); PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU8ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_LOGGING, ipRule->logging), ERR_BAD_PARAM); if (ipRule->ipRule.ipValid.sIpEnable) { char sipStr[IP_ADDRESS_LENGTH] = {}; char sipMaskStr[IP_ADDRESS_LENGTH] = {}; FPT_IPADDR_ARRAY_TO_IPSTR(ipRule->ipRule.sourceAddress.ipAddr, sipStr); FPT_IPADDR_ARRAY_TO_IPSTR(ipRule->ipRule.sourceAddressMask.ipAddr, sipMaskStr); PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldStrForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_SIP, sipStr), ERR_BAD_PARAM); PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldStrForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_SIP_MASK, sipMaskStr), ERR_BAD_PARAM); } if (ipRule->ipRule.ipValid.dIpEnable) { char dipStr[IP_ADDRESS_LENGTH] = {}; char dipMaskStr[IP_ADDRESS_LENGTH] = {}; FPT_IPADDR_ARRAY_TO_IPSTR(ipRule->ipRule.destAddress.ipAddr, dipStr); FPT_IPADDR_ARRAY_TO_IPSTR(ipRule->ipRule.destAddressMask.ipAddr, dipMaskStr); PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldStrForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_DIP, dipStr), ERR_BAD_PARAM); PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldStrForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_DIP_MASK, dipMaskStr), ERR_BAD_PARAM); } if(ipRule->ipRule.ipValid.ipDscpValid) { PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU8ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_DSCP, ipRule->ipRule.ipDscp), ERR_BAD_PARAM); } if(ipRule->ipRule.ipValid.ipTosValid) { PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU8ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_TOS, ipRule->ipRule.ipTos), ERR_BAD_PARAM); } if(ipRule->ipRule.ipValid.ipPreValid) { PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU8ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_PRE, ipRule->ipRule.ipPre), ERR_BAD_PARAM); } if(ipRule->ipRule.ipValid.ipProtoValid) { PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU8ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_IP_PROTO, ipRule->ipRule.ipProto), ERR_BAD_PARAM); } if(ipRule->ipRule.ipValid.l4SourcePortValid) { PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU32ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_SPORT, ipRule->ipRule.fptL4Struct.sport), ERR_BAD_PARAM); PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU32ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_SPORT_MASK, ipRule->ipRule.fptL4Struct.spMask), ERR_BAD_PARAM); } if(ipRule->ipRule.ipValid.l4DestPortValid) { PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU32ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_DPORT, ipRule->ipRule.fptL4Struct.dport), ERR_BAD_PARAM); PFM_IF_FAIL_RET_VAL(tpConfig_objAddFieldNumU32ForSet(stInput, TPCONFIG_INIT_ENTRY, IP_FPT_RULE_DPORT_MASK, ipRule->ipRule.fptL4Struct.dpMask), ERR_BAD_PARAM); } return ERR_NO_ERROR; }
最新发布
10-01
<think>好的,用户让我介绍一下C语言运算符的优先级。首先,我需要回忆一下C语言中运算符的分类和它们的优先级顺序。可能用户是刚开始学习C语言,或者对某些运算符的优先级有困惑,导致代码运行结果不符合预期。所以,我需要详细但清晰地解释,帮助他们理解这个概念。 首先,我应该从运算符优先级的基本概念入手,说明为什么需要优先级,以及优先级的作用。然后,列出主要的运算符类别,按照从高到低的顺序排列,每个类别给出例子,这样用户更容易记忆。 接下来,我需要确保分类正确。比如,括号和成员访问运算符属于最高优先级,然后是单目运算符,比如递增、取地址等。之后是算术运算符,先乘除取模,后加减。移位运算符可能在关系运算符之前还是之后?这里需要确认正确的顺序。比如,移位运算符的优先级应该低于算术运算符,但高于关系运算符。 然后,关系运算符(如<、>、<=、>=)之后是等于和不等于运算符,接着是位运算符,按位与、异或、或,然后是逻辑运算符,比如&&和||。条件运算符(?:)和赋值运算符的优先级较低,逗号运算符最低。 需要注意一些常见的易错点,比如逻辑与&&的优先级高于逻辑或||,而位运算符的优先级可能低于关系运算符,这可能导致意想不到的结果。例如,if (a & 0x0F == 0)这样的表达式,由于==的优先级高于&,会导致错误的结果,应该加括号。 另外,赋值运算符的右结合性也是一个需要注意的地方,比如a = b = c会被处理成a = (b = c)。同时,条件运算符的结合性也需要解释清楚。 可能用户在实际编程中遇到问题时,比如表达式计算顺序不符合预期,这时候了解优先级可以避免错误。因此,给出一些常见的错误示例和正确写法会有帮助。 总结时,需要强调当不确定优先级时,使用括号来明确顺序是一个好习惯,同时提供参考资料供用户进一步学习。 现在,我需要将以上思考整理成一个结构清晰的回答,按照优先级从高到低列出主要类别,每个类别给出运算符和例子,并指出常见注意事项和错误。确保使用正确的中文术语,并且例子使用正确的LaTeX格式,行内公式用$...$,独立公式用$$...$$,不过在这个回答中可能不需要独立公式,所以主要用行内格式。</think>C语言运算符优先级决定了表达式中各运算符的执行顺序。当表达式包含多个运算符时,优先级高的先计算,优先级相同的则根据结合性(从左到右或从右到左)决定顺序。以下是主要优先级层级(从高到低): --- ### 一、最高优先级 1. **括号与成员访问** `()` 函数调用、类型转换;`[]` 数组下标;`.` 结构体成员;`->` 指针成员 *例*: ```c (a + b) * c; // 括号优先 arr[3] = 10; // 数组下标 ``` --- ### 二、单目运算符 2. **单目运算符** `++`(后缀/前缀)、`--`(后缀/前缀)、`!`(逻辑非)、`~`(按位取反)、`+`(正)、`-`(负)、`&`(取地址)、`*`(解引用)、`sizeof` *例*: ```c *ptr++; // 等价于 *(ptr++) -x + y; // 先计算 -x ``` --- ### 三、算术运算符 3. **乘除取模** `*`(乘)、`/`(除)、`%`(取余) *例*: ```c 3 + 5 * 2; // 先计算5*2=10,再3+10=13 ``` 4. **加减** `+`(加)、`-`(减) *例*: ```c a + b << 2; // 先计算a+b,再左移 ``` --- ### 四、移位运算符 5. **位移** `<<`(左移)、`>>`(右移) *例*: ```c 1 << 2 + 3; // 等价于1 << (2+3)=32 ``` --- ### 五、关系运算符 6. **大小比较** `<`、`<=`、`>`、`>=` *例*: ```c a < b == c; // 先比较a < b,再判断结果是否等于c ``` 7. **相等性判断** `==`(等于)、`!=`(不等于) --- ### 六、位运算符 8. **按位与** `&` 9. **按位异或** `^` 10. **按位或** `|` --- ### 七、逻辑运算符 11. **逻辑与** `&&` 12. **逻辑或** `||` --- ### 八、条件与赋值 13. **条件运算符** `?:`(右结合) *例*: ```c a > b ? a : c > d ? c : d; // 等价于a > b ? a : (c > d ? c : d) ``` 14. **赋值运算符** `=`, `+=`, `-=`, `*=`, `/=`等(右结合) *例*: ```c a = b = 5; // 等价于a = (b = 5) ``` 15. **逗号运算符** `,`(优先级最低) *例*: ```c a = (b=3, b+2); // a最终为5 ``` --- ### 常见注意事项 1. **易错点** - `if (a & 0x0F == 0)` ❌ 因`==`优先级高于`&`,应写为`if ((a & 0x0F) == 0)` ✅ - `*ptr++` 等价于 `*(ptr++)`,而非 `(*ptr)++` 2. **结合性规则** - 多数运算符从左到右结合,但赋值、单目、条件运算符从右到左。 --- ### 总结建议 - **不确定时加括号**:明确优先级可避免歧义。 - **参考表格**:查阅完整的C运算符优先级表(如[cppreference](https://en.cppreference.com/w/c/language/operator_precedence))辅助记忆。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值