C语⾔之运算符,表达式和语句总结
⽬录
前⾔
C语⾔为我们提供了品种繁多的运算符(⼤约40个),这个特点使得它很难被精通,但是C的许多运算符具有其他语⾔的运算符⽆可抗衡的价值。本⽂是对⼀些常⽤的运算符进⾏总结,以及表达式和语句的知识点的归纳
⼀、各种运算符
Ⅰ、算术运算符
1.加法运算符:+
⽤于加法运算,相加的值可以是变量也可以是常量。如printf("%d",4+20);  income = salary + bribes;均是正确表达。
2.减法运算符:-
⽤于减法运算,使其左侧的值减去右侧的值
3.乘法运算符:*
⽤于乘法运算,不同于数学上的'x'。
4.除法运算符:/
(1)⽤于除法运算,不同于数学上的‘÷’。/左侧是被除数,/右侧是除数。
(2)整数除法和浮点数除法不同。浮点数除法的结果是浮点数,整数除法的结果是整数。
#include <stdio.h>
int main()
{
printf("%d\n",5 / 4);
printf("%d\n",6 / 3);
printf("%.2f\n",7. / 4.);
printf("%.2f\n",7. / 4);
return 0;
}
编译并运⾏代码,输出如下:
1    //整型除法会截断计算结果的⼩数部分(丢弃整个⼩数部分),不会四舍五⼊
2
1.75
1.75    //整数和浮点数的计算结果是浮点数,实际上,计算机不会真正⽤浮点数除以整数,编译器会把两个运算对象转换成相同类型
(3)负数如何截断?如-3.8是变成-3还是-4,“趋零截断”这⼀概念告诉我们-3.8会被处理成-3
5.求模运算符:%
(1)⽤于整数运算,不能⽤于浮点数,求模运算符给出其左侧整数除以右侧整数的余数。13%5(读作:13求模5)。
(2)求模运算符常⽤于控制程序流
(3)负数求模:如果第⼀个运算对象为负数,那么求模结果为负数;如果第⼀个运算对象为正数,那么求模结果为正数
6.符号运算符:+和-
⽤于标明或改变⼀个值的代数符号。它们是⼀元运算符(单⽬运算符),即只需要⼀个运算对象。
7.递增运算符:++
(1)功能:将其运算对象递增1
(2)两种形式:①前缀模式:++出现在其作⽤的变量前⾯
②后缀模式:++出现在其作⽤的变量后⾯
(3)这种缩写形式的好处:让程序更加简洁、美观,可读性更⾼。
(4)前缀模式:先++,再使⽤
后缀模式:先使⽤,再++
#include <stdio.h>
int main()
{
int a = 1,b = 1;
int a_post,pre_b;
a_post = a++;
pre_b = ++b;
printf("a  a_post  b  pre_b \n");
printf("%d %7d %2d %6d\n", a, a_post, b, pre_b);
return 0;
}
编译并运⾏该代码,输出如下:
a  a_post
b  pre_b
2          1  2        2
可以看到后缀模式:使⽤a的值之后,递增a                                                                                                                                                    前缀模式:使⽤b的值之前,递增b
8.递减运算符:--
与++同理。
Ⅱ、赋值运算符
1.赋值运算符:=
1°、⼀些术语:
(1)数据对象:⽤于存储值的数据存储区
(2)左值:⽤于标识特定数据对象的名称或表达式。
Tips:提到左值,这意味着它①指定⼀个对象,可以引⽤内存中的地址②可以⽤在赋值运算符的左侧。但是const创建的变量不可修改,不满⾜②,所以后来⼜提出了可修改的左值这⼀概念,⽤于标识可修改的对象
(3)右值:能赋值给可修改左值的量,且本⾝不为左值
2°、在C语⾔中,=不意味着“相等”,⽽是⼀个赋值运算符,num = 2021,读作“把值2021赋给变量num”,赋值⾏为从右往左进⾏
3°、2021 = num;?在C语⾔中类似这样的语句是没有意义的,因为此时,2021被称为右值,只能是字符常量,不能给常量赋值,常量本⾝就是它的值。因此,我们要记住赋值运算符左侧必须引⽤⼀个存储位置,最简单的⽅法就是使⽤变量名。C使⽤可修改的左值标记那些可赋值的实体。
4°、C语⾔中不回避三重赋值,赋值顺序从右向左,如a = b = c = 100;⾸先把100赋给从c,然后再赋给b,最后赋给a。
关于左值,右值,我们来看以下代码例⼦:
#include <stdio.h>
int main()
{
int ex, why, zee;//ex,why,zee都是可修改的左值
const int TWO = 2;//TWO是不可修改的左值,只能放在=的右侧,此处的=是初始化,不是赋值,因此并没有违反规则
why = 42;
zee = why;
ex = TWO * (why + zee);//(why + zee)是右值,该表达式不能表⽰特定内存位置,⽽且也不能给它赋值
return 0;
}
2.其他赋值运算符:+=、-=、*=、/=、%=
c语言中逗号表达式的用法
(1)以下每⼀⾏的左右两种表达等价
scores += 20score = score + 20
dimes -= 2dimes = dimes - 2
bunnies *= 2bunnies = bunnies * 2
time /= 2.73time = time /2.73
reduce %= 3reduce = reduce % 3
(2)优点:让代码更紧凑,与⼀般形式相⽐,组合形式的赋值运算符⽣成的机器代码更⾼效
3.以上两⼤类运算符优先级和求值顺序问题
(1)
运算符优先级(由⾼⾄低)
运算符结合律
()从左往右
+  -    ++    --(单⽬)从右往左
*    /从左往右
+    -(双⽬)从左往右
=  +=  -=  *=  /=  %=从右往左
Tip:如果两个运算符优先级相同,则根据它们在语句中出现的顺序来执⾏
(2)虽然运算符的优先级为表达式中的求值顺序提供了重要依据,但是并没有规定所有的顺序。如:⽤ y= 6 * 12 + 5 * 20;由(1)可知,先进⾏6 * 12和5 * 20,再进⾏加法运算,但是优先级并没有规定先进⾏哪个乘法。C语⾔把主动权交给语⾔的实现者,根据不同的硬件来决定先计算前者还是后者,但是⽆论采取何种⽅案,都不会影响最终结果。结合律适⽤于共享同⼀运算对象的运算符,如:12 / 3 * 2,/和*的优先级相同,共享运算符3,所以从左往右的结合律可以起作⽤。
(3)如果⼀个变量出现在⼀个函数的多个参数中,不要对该变量使⽤递增或递减运算符;如果⼀个变量多次出现在⼀个表达式中,不要对该变量使⽤递增或递减运算符。举个例⼦:ans = num/2 + 5*(1 + num++);我们可能会认为,先计算第⼀项(num/2),接着计算(5* (1 + num++));但是编译器可能先计算第⼆项,递增num,然后在num/2中使⽤num递增后的新值
Ⅲ、关系运算符
1.
关系运算符
<⼩于
>⼤于
<=⼩于等于
>=⼤于等于
==等于
!
=不等于
结合律:从左向右
2.⽤关系运算符将两个表达式连接起来的式⼦,称为关系表达式。关系表达式的结果是⼀个逻辑量,取值“真”或“假”,
即“1”或“0”。
3.优先级:赋值<;关系<;算术。所以x > y + 2和x > (y + 2)相同;x = y >2和x = (y >2)相同,若y>2,给x赋值为1,否则赋值为0
关系运算符之间的优先级
⾼优先级组<  >  <=  >=
低优先级组==  !=
4.如果待⽐较的值是⼀个常量,可以把该常量放在左侧有助于编译器捕获错误,如:5 = canoes是⼀种语法错误,⽽5 == canoes可以检查 canoes的值是否为5。这是因为C语⾔不允许给常量赋值,编译
器会把赋值运算符的这种⽤法作为语法错误标记出来。我们再构建⽐较是否相等的表达式时可以把常量放在左侧。
Ⅳ、逻辑运算符
1.与关系运算⼀样,⽤整数1代表“真”,⽤整数0代表“假”
2.
逻辑运算符
⽬数单⽬                                双⽬
运算符!&&||
名称逻辑⾮逻辑与逻辑或
假设exp1和exp2是两个简单的关系表达式,那么:
(1)当且仅当exp1和exp2都为真时,exp1 && exp2才为真
(2)如果exp1或exp2为真,则exp1 || exp2为真
(3)如果exp1为真,则!exp1为假;如果exp1为假,则!exp1为真
3.&& 和 ||都是序列点,所以程序在从⼀个运算对象执⾏到下⼀个运算对象之前,所有的副作⽤都会⽣效。
4.&&可⽤于测试范围,如测试score是否在90~100的范围,可以这样写 if(score >= 90 && score <= 100)
printf ("Good!\n");
但是不可以写成if(90 <= score <= 100)
printf("Good!\n");
这是代码的语义错误,不是语法错误,因此编译器并不会捕捉这样的问题。<=的求值顺序为从左到右,⼦表达式90 <= score的值要么为1,要么为0,这两个值都⼩于100,所以不管score的值是多少,整个表达式都恒为真。
5.与其他表达式的运算过程不同,在求解&&和||连接的逻辑表达式时,按从左到右的顺序计算该运算符两侧的操作数,⼀旦能得到表达式的结果,就停⽌运算。(1)exp1 && exp2,先计算exp1,若其值为0,则exp1 && exp2的值⼀定为0(2)exp1 || exp2,先计算
exp1,若其值为⾮0,则exp1 && exp2的值⼀定为1
如:
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a = %d,b = %d,c = %d,d = %d\n", a, b, c, d);
return 0;
}
编译并运⾏该代码,输出如下:
a = 1,
b = 2,
c = 3,
d = 4
//后置++,先使⽤再++,使⽤时,a = 0,为假,后⾯的已经没有必要算了
//i = 0
4.优先级:
逻辑运算符优先级(由⾼⾄低)
&&    ||
Ⅴ、条件运算符(?:)
1.作为if else语句的⼀种便携⽅式。是C语⾔中唯⼀的三⽬运算符(带三个运算对象)
2.通⽤形式:expression1?expression2:expression3    (结合律:从左向右)
如果expression1为真,那么整个条件表达式的值与expression2相同;如果expression1为假,那么整个条件表达式的值与expression3相同

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。