Loading... # 二、运算符与表达式 ## 1.算数运算符 C语言提供了 13 种类型的运算符, 如下所示。 **(1) 算术运算符 (+-*/ %) .** **(2) 关系运算符 (> < == >= <= !=) .** **(3) 逻辑运算符(!&&‖) .** (4) 位运算符(<<>>~|^&) 。 (**5) 赋值运算符(=及其扩展赋值运算符) 。** (6) 条件运算符(?:) 。 (7) 逗号运算符(,) 。 (8) 指针运算符(*和&) 。---讲指针时讲解 **(9) 求字节数运算符(sizeof) .** **(10) 强制类型转换运算符 ((类型)) .** (11) 分量运算符(.->) 。---讲结构体时讲解 (12) 下标运算符 ([]) 。 ----讲数组时讲解 (13) 其他(如函数调用运算符()) 。---讲函数时讲解 ## 2 .算术运算符及算术表达式 算术运算符包含+、-、\*、/和%,**乘、除、取余运算符的优先级高于加、减运算符。**除%运算符外, 其余几种运算符既适用于浮点型数又适用于整型数。当操作符/的两个操作数都是整型数时, 它执行整除运算, 在其他情况下执行浮点型数除法。**%为取模运算符, 它接收两个整型操作数,** 将左操作数除以右操作数, 但它的返回值是余数而不是商。由算术运算符组成的式子称为算术表达式, 表达式一定有一个值。 ```c #include <stdio.h> //练习算术运算符 int main() { int result=4+5*2-6/3+11%4; //15 printf("result=%d\n",result); return 0; } ``` ## 3.关系运算符与关系表达式 关系运算符>、<、==、>=、<=、!=依次为大于、小于、是否等于、大于等于、小于等于和不等于, 由关系运算符组成的表达式称为关系表达式。**关系表达式的值只有真和假**, 对应的值为1和0. 由于 C语言中没有布尔类型, 所以在C语言中O值代表假,非0值即为真.例如, 关系表达式3>4为假, 因此整体值为0, 而关系表达式5>2为真, 因此整体值为1. **关系运算符的优先级低于算术运算符**, 当判断整型变量 i是否等于3时, 我们可以写为3==i, 即把常量写在前面而把变量写在后面.这是因为当不小心将两个等号写为一个等号时, 变量在前面就会导致编译不通, 从而快速发现错误 同时,在编写程序时,如果我们需要判断三个数是否相等,那么绝对不可以写为 if(5\=\=5\=\=5),这种写法的值无论何时都为假, 为什么? 因为首先 5\=\=5 得到的结果为1, 然后1\=\=5得到的结果为0. 如果要判断三个变量a、b、c是否相等, 那么不能写为a\=\=b\=\=c, 而应写为 a\=\=b&&b\=\=c. 下面来看一个例子. ```c #include <stdio.h> //关系运算符,优先级小于算术运算符 int main() { int a; while(scanf("%d",&a)) { if(3<a && a<10)//a大于3同时a小于10要这样写 { printf("a is between 3 and 10\n"); }else{ printf("a is not between 3 and 10\n"); } } return 0; } ``` 如果要判断变量 a 是否大于3且同时小于 10, 那么不能写为3<a<10, 首先, 无论a是大于3还是小于3, 对于3<a这个表达式只有1或0两种结果。 由于1和0都是小于10的, 所以无论a的值为多少, 这个表达式的值始终为真, 因此在判断变量a是否大于3且同时小于 10时, 要写成:a>388a<10,, 这才是正确的写法. ## 4.运算符优先级表 | 优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 | | :----- | :------: | :--------------- | :------------------------- | :--------- | :--------- | | 1 | \[\] | 数组下标 | 数组名\[常量表达式\] | 左到右 | | | 1 | \(\) | 圆括号 | \(表达式\)函数名\(形参表\) | 左到右 | | | 1 | \. | 成员选择(对象) | 对象.成员名 | 左到右 | | | 1 | \-\> | 成员选择(指针) | 对象指针\-\>成员名 | 左到右 | | | 2 | \- | 负号运算符 | \-表达式 | **右到左** | 单目运算符 | | 2 | \(类型\) | 强制类型转换 | (数据类型)表达式 | **右到左** | | | 2 | \+\+ | 自增运算符 | \+\+变量名/变量名\+\+ | **右到左** | 单目运算符 | | 2 | \-\- | 自减运算符 | \-\-变量名/变量名\-\- | **右到左** | 单目运算符 | | 2 | \* | 取值运算符 | \*指针变量 | **右到左** | 单目运算符 | | 2 | \& | 取地址运算符 | \&变量名 | **右到左** | 单目运算符 | | 2 | \! | 逻辑非运算符 | \!表达式 | **右到左** | 单目运算符 | | 2 | ~ | 按位取反运算符 | ~表达式 | **右到左** | 单目运算符 | | 2 | sizeof | 长度运算符 | sizeof\(表达式\) | **右到左** | | | 3 | / | 除 | 表达式 / 表达式 | 左到右 | 双目运算符 | | 3 | \* | 乘 | 表达式\*表达式 | 左到右 | 双目运算符 | | 3 | % | 余数(取模) | 整型表达式%整型表达式 | 左到右 | 双目运算符 | | 4 | \+ | 加 | 表达式\+表达式 | 左到右 | 双目运算符 | | 4 | \- | 减 | 表达式\-表达式 | 左到右 | 双目运算符 | | 5 | \<\< | 左移 | 变量\<\<表达式 | 左到右 | 双目运算符 | | 5 | \>\> | 右移 | 变量\>\>表达式 | 左到右 | 双目运算符 | | 6 | \> | 大于 | 表达式\>表达式 | 左到右 | 双目运算符 | | 6 | \>\= | 大于等于 | 表达式\>\=表达式 | 左到右 | 双目运算符 | | 6 | \< | 小于 | 表达式\<表达式 | 左到右 | 双目运算符 | | 6 | \<\= | 小于等于 | 表达式\<\=表达式 | 左到右 | 双目运算符 | | 7 | \=\= | 等于 | 表达式\=\=表达式 | 左到右 | 双目运算符 | | 7 | \!\= | 不等于 | 表达式\!\= 表达式 | 左到右 | 双目运算符 | | 8 | \& | 按位与 | 表达式\&表达式 | 左到右 | 双目运算符 | | 9 | \^ | 按位异或 | 表达式\^表达式 | 左到右 | 双目运算符 | | 10 | \| | 按位或 | 表达式\|表达式 | 左到右 | 双目运算符 | | 11 | \&\& | 逻辑与 | 表达式\&\&表达式 | 左到右 | 双目运算符 | | 12 | \|\| | 逻辑或 | 表达式\|\|表达式 | 左到右 | 双目运算符 | | 13 | ?\: | 条件运算符 | 表达式1? 表达式2\: 表达式3 | **右到左** | 三目运算符 | | 14 | \= | 赋值运算符 | 变量\=表达式 | **右到左** | | | 14 | /\= | 除后赋值 | 变量/\=表达式 | **右到左** | | | 14 | \*\= | 乘后赋值 | 变量\*\=表达式 | **右到左** | | | 14 | %\= | 取模后赋值 | 变量%\=表达式 | **右到左** | | | 14 | \+\= | 加后赋值 | 变量\+\=表达式 | **右到左** | | | 14 | \-\= | 减后赋值 | 变量\-\=表达式 | **右到左** | | | 14 | \<\<\= | 左移后赋值 | 变量\<\<\=表达式 | **右到左** | | | 14 | \>\>\= | 右移后赋值 | 变量\>\>\=表达式 | **右到左** | | | 14 | \&\= | 按位与后赋值 | 变量\&\=表达式 | **右到左** | | | 14 | \^\= | 按位异或后赋值 | 变量\^\=表达式 | **右到左** | | | 14 | \|= | 按位或后赋值 | 变量\|=表达式 | **右到左** | | | 15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | | 同一优先级的运算符,运算次序由结合方向所决定。 简单记就是: ! \>算术运算符\>关系运算符\>\&\&\> || >赋值运算符 ## 5.逻辑运算符与逻辑表达式 逻辑运算符!、&&、‖依次为逻辑非、逻辑与、逻辑或,这和数学上的与、或、非是一致的。**逻辑非的优先级高于算术运算符, 逻辑与和逻辑或的优先级低于关系运算符**,逻辑表达式的值只有真和假, ```c #include <stdio.h> //记住优先级目的,不能够加多余的括号 int main() { int year,i,j=6; while(scanf("%d",&year)) { if(year%4==0&&year%100!=0 || year%400==0) { printf("%d is leap year\n",year); }else{ printf("%d is not leap year\n",year); } } i=!!j; printf("i value=%d\n",i); return 0; } ``` 针对代码中的逻辑非, 首先给变量j赋值 6, 因为j 的值非0, 所以!j 的值为0; 然后, 由于逻辑非是单目运算符, 结合顺序为从右至左, 得到!!j的值为1。也就是说, 对0取非, 得到的值为 1; 对非0值取非, 得到的值为0. ==短路运算== ```c #include <stdio.h> //逻辑与和逻辑或 短路运算 int main() { int i=0; i&&printf("you can't see me !\n");//当i为假时,不会执行逻辑与后的表达式,称为短路运算 i=1; i||printf("you can't see me !\n"); return 0; } ``` 逻辑与短路运算是当前面一个表达式为假时, 后面的表达式不会得到执行, 逻辑或短路运算是当前面一个表达式为真时, 后面的表达式不会得到执行 ## 6.赋值运算符 为了理解有些操作符存在的限制, 必须理解左值 (L-value) 和右值(R-value) 之间的区别。这两个术语多年前由编译器设计者创造并沿用至今, 尽管它们的定义与C语言并不严格吻合。 左值是那些能够出现在赋值符号左边的东西, 右值是那些可以出现在赋值符号右边的东西。例如,a = b+25;其中, a 是一个左值, 因为它标识了一个可以存储结果值的地点; b + 25是一个右值, 因为它指定了一个值. 它们可以互换吗? 比如:b + 25 = a;因为每个位置都包含一个值, 所以原先用作左值的a 此时也可以作为右值; 然而, b+25不能作为左值, **因为它并未标识一个特定的位置(并不对应特定的内存空间) . 因此, 上面这条赋值语句是非法的。** **复合赋值运算符:** 复合赋值运算符操作是一种缩写形式, 使用复合赋值运算符能使对变量的赋值操作变得更加简洁, 例如, ```c iNum = iNum + 5; ``` 对变量 iNum的赋值进行操作, 值为这个变量本身与一个整型常量5 相加的结果.使用复合语句可以实现同样的操作。例如, 上面的语句可以修改为 ```c iNum+=5; ``` 赋值运算符与复合赋值运算符的区别如下: (1) 复合赋值运算符简化了程序, 可使程序精炼, 提升阅读速度。 (2) 复合赋值运算符提高了编译效率。 下例说明了加后赋值与乘后赋值的用法。 ```c #include <stdio.h> //赋值的练习 int main() { int a=1,b=2; a+=3; b*=5; printf("a=%d\n",a); printf("b=%d\n",b); return 0; } ``` 上面的程序代码可以看到,a+=3代表a加3 后再赋值给a, 因此a的最终值为4, 而 b的值等于5乘以b的值, 所以最终结果为10。 ## 7.求字节运算符 很多同学会认为 sizeof是一个函数, 这种理解是错误的, 实际sizeof是一个运算符, 不像其他运算符是一个符号, sizeof是字母组成的, 用于求常量或变量所占用的空间大小,例: ```c #include <stdio.h> //sizeof运算符 int main() { int i=0; printf("i size is %d\n",sizeof(i)); return 0; } ``` 运行结果为 i size is 4, 可以求得整型变量占用的空间大小是 4个字节。 End 本文作者: 彼岸花露 文章标题:二、运算符与表达式(C语言) 本文地址:https://blog.tianlei.work/archives/105/ 版权说明:若无注明,本文皆悟思记原创,转载请保留文章出处。 最后修改:2024 年 04 月 12 日 © 允许规范转载 赞 3 如果觉得我的文章对你有用,请随意赞赏
此处评论已关闭