C语言中的运算符优先级「代码示例」

1. 运算符优先级的定义

在C语言中,运算符优先级是由编译器按照一定规则预先定义的,用于确定运算符之间的执行优先级。在进行表达式运算时,编译器按照运算符优先级来确定运算符的执行顺序,从而获取正确的表达式运算结果。

下面是C语言中常用的运算符优先级从高到低的顺序表:

()

// 括号,强制优先级

! ~ ++ -- + -

// 一元运算符

* / %

// 乘、除、取余

+ -

// 加、减

<< >>

// 左移、右移

< <= > >=

// 小于、小于等于、大于、大于等于

== !=

// 等于、不等于

&

// 按位与

^

// 按位异或

|

// 按位或

&&

// 逻辑与

||

// 逻辑或

?:

// 条件运算符

= += -= *= /= %=

// 赋值运算符

,

// 逗号,用于分隔表达式

需要注意的是,优先级高的运算符并不一定比优先级低的运算符先执行,这还要考虑到运算符的结合性(左结合和右结合)。

2. 左结合和右结合

2.1 左结合

对于优先级相同的运算符,C语言默认采取左结合(left-associative)的方式来进行运算。

所谓左结合,就是指相同优先级的运算符从左往右执行。比如,对于如下的表达式:

int a = 1, b = 2, c = 3;

a + b + c;

因为加法运算符具有左结合性,所以会先计算a+b的值,再和c相加。相当于以下表达式:

(a+b)+c;

2.2 右结合

有些运算符,比如赋值运算符和三目运算符,采用的是右结合(right-associative)方式进行运算。

所谓右结合,就是指相同优先级的运算符从右往左执行。

以赋值运算符为例,如下的赋值语句:

int a = 5, b = 10, c = 20;

a = b = c;

因为赋值运算符的优先级比等于号要低,而且赋值运算符采用的是右结合,所以先执行b=c,再执行a=b,最终a、b、c的值都变成了20。

3. 运算符优先级示例

3.1 算术运算符的优先级

算术运算符包括加、减、乘、除、取余等运算符,其优先级从高到低为:

* / %

+ -

这意味着,乘、除、取余优先级高于加、减。下面的示例演示了算术运算符的优先级:

#include <stdio.h>

int main()

{

int a = 5, b = 3, c = 8;

int result = a + b * c;

printf("a + b * c = %d\n", result);

return 0;

}

这个例子中,由于乘法运算符的优先级高于加法运算符,所以先计算b*c的结果,然后再加上a的值,最终得到23。

3.2 逻辑运算符的优先级

逻辑运算符包括与、或、非等运算符,其优先级从高到低为:

!

&&

||

这意味着,非运算符的优先级高于与运算符,与运算符的优先级高于或运算符。下面的示例演示了逻辑运算符的优先级:

#include <stdio.h>

int main()

{

int a = 5, b = 3, c = 0;

int result = (a > b) && (c != 0);

printf("(a > b) && (c != 0) = %d\n", result);

return 0;

}

这个例子中,由于与运算符的优先级高于或运算符,所以先计算(a>b)的结果,再计算(c!=0)的结果,最后将它们用与运算符连接起来,得到结果0。

3.3 关系运算符的优先级

关系运算符包括小于、小于等于、大于、大于等于、等于和不等于等运算符,其优先级从高到低为:

< <= > >=

== !=

这意味着,小于、小于等于、大于、大于等于优先级高于等于和不等于。下面的示例演示了关系运算符的优先级:

#include <stdio.h>

int main()

{

int a = 5, b = 3, c = 8;

int result = (a > b) != (c < a);

printf("(a > b) != (c < a) = %d\n", result);

return 0;

}

这个例子中,由于小于运算符的优先级低于不等于运算符,所以先计算cb的结果,最后将它们用不等于运算符连接起来,得到结果1。

3.4 赋值运算符的优先级

C语言中的赋值运算符不仅仅是一个等于号,还可以和其他运算符组合形成不同的赋值运算。

赋值运算符的优先级是从右往左依次降低的。比如,先计算右边表达式的值,然后再把它赋值给左边的变量。

下面的表格列出了常见的赋值运算符及其组合形式,从上到下优先级依次降低:

赋值运算符组合表达式
=x = 5
+=x += 5
-=x -= 5
*=x *= 5
/=x /= 5
%=x %= 5
<<=x <<= 2
>>=x >>= 2
&=x &= 5
^=x ^= 5
|=x |= 5

下面的示例演示了赋值运算符的优先级:

#include <stdio.h>

int main()

{

int a = 5, b = 3, c = 8;

a += b *= c %= 3;

printf("a = %d, b = %d, c = %d\n", a, b, c);

return 0;

}

这个例子中,由于赋值运算符的优先级从右往左依次降低,所以先计算c%=3的结果(等价于c=c%3),再计算b*=2的结果(等价于b=b*2),最后将结果赋值给a,得到a的值为11,b的值为16,c的值为2。

3.5 其他运算符的优先级

对于其他运算符,比如位运算符、条件运算符等,其优先级是由它们本身的功能决定的。

位运算符包括按位与、按位或、按位异或等运算符。以按位与运算符为例,其优先级低于关系运算符,高于赋值运算符。下面的示例演示了位运算符的优先级:

#include <stdio.h>

int main()

{

int a = 5, b = 3, c = 8;

int result = (a < b) & (c > b);

printf("(a < b) & (c > b) = %d\n", result);

return 0;

}

这个例子中,由于位运算符的优先级低于关系运算符,所以先计算a<b和c>b的结果,最后将它们用按位与运算符连接起来,得到结果0。

条件运算符由问号和冒号组成,其优先级低于逻辑运算符,高于赋值运算符。下面的示例演示了条件运算符的优先级:

#include <stdio.h>

int main()

{

int a = 5, b = 3;

int result = (a > b) ? a : b;

printf("(a > b) ? a : b = %d\n", result);

return 0;

}

这个例子中,由于条件运算符的优先级低于逻辑运算符,所以先计算a>b的结果,然后根据结果选择a或b的值,最终得到结果5。

4. 总结

在C语言中,运算符优先级和结合性是编译器预先定义的,用于确定运算符之间的执行顺序以获取正确的表达式运算结果。

常用的运算符有算术运算符、逻辑运算符、关系运算符、赋值运算符、位运算符、条件运算符等,需要根据它们的优先级和结合性来编写正确的表达式,避免因为优先级问题导致程序出错。

后端开发标签