表达式
表达式是由操作数和运算符构成,操作数本身也可以是一个表达式。
表达式再在其后加一个分号,即构成 C 语言语句。
运算符优先级/结合性/分类
不同优先级的运算符,运算次序按优先级由高到低执行。
同一优先级的运算符,运算次序按结合方向的规定执行。
常见运算符及构成的表达式
注意:所有表达式既有类型,也是有值的。
赋值运算符与赋值表达式
赋值运算符列表
赋值运算符说明
把右侧表达式的值赋给左侧的变量;表达式的值等于左值。
运算符两侧类型不一致时,要进行类型转换。
赋值表达式可嵌套。
复合赋值运算符是一种简洁的需要。
赋值运算符代码演示
代码演示:
#include <stdio.h>
int main()
{
int a, b, c;
a = 5; //表达式的值为 5
a = b = 3; //a=(b=3)
a += b; //等价于 a = a + b
a -= b; //等价于 a = a - b
a *= b; //等价于 a = a * b
a /= b; //等价于 a = a / b
a = (b = 4) + (c = 3);
//表达式 (b = 4) 值为4
//表达式 (c = 3) 值为3
//a 为两个表达式值相加 4 + 3
a *= b + c; //等价于 a = a * (b + c)
return 0;
}
算术运算符与算术表达式
算术运算符列表
算术运算符说明
" / " --除法运算,如果参与运算的两个操作数皆为整数,那么结果也为整数,此处直接取整 ,没有四舍五入的说法。
如果其中有一个是浮点数,那么运算结果一定是浮点数。
" % " 数学语言中,除数除以被除数得商和余数,是一体化的。但是 c 语言中却是分开的。
%表示求余运算,且求余运算的操作数只能是整型数据。
% 求余运算符要求操作数必须为整型,为什么不可以是浮点型呢?
因为浮点数不存在求余问题。
++/- -运算独立:前++ 后++ 没有区别。
若运算不独立则会有先使用和先运算之分:
后++,先使用再自增1。
前++,先自增1再使用。
后–,先使用后自减1。
前–,先自减1后使用。
自增与自减运算也是一种 c 语言简洁的需要。
算术运算符代码演示
代码演示:
#include <stdio.h>
int main()
{
int a = 10; int b = 3;
int ires = a / b;
printf("ires = %d\n", ires); //3
float c = 3.0;
float fres = a / c;
printf("fres = %f\n", fres); //3.333333
int iret = 10 / 3;
printf("ret = %d\n", iret); //3
float fret = (float)10 / 3; //在此实现的是得到 3.33333
printf("fret = %f\n", fret); //3.333333
//后置自加运算不独立, 参与其他表达式构成
b = a++;
printf("a = %d b = %d\n", a, b);//11 10
//前置自加运算不独立, 参与其他表达式构成
b = ++a;
printf("a = %d b = %d\n", a, b);//12 12
//后置自减运算不独立, 参与其他表达式构成
b = a--;
printf("a = %d b = %d\n", a, b);//11 12
//前置自减运算不独立, 参与其他表达式构成
b = --a;
printf("a = %d b = %d\n", a, b);//10 10
//后置自加运算独立
a++;
b++;
printf("a = %d b = %d\n", a, b);//11 11
//前置自加运算独立
++a;
++b;
printf("a = %d b = %d\n", a, b);//12 12
//后置自减运算独立
a--;
b--;
printf("a = %d b = %d\n", a, b);//11 11
//前置自减运算独立
a--;
b--;
printf("a = %d b = %d\n", a, b);//10 10
return 0;
}
运行结果:
关系运算符与关系表达式
关系运算符列表
关系运算符说明
关系表达式值,成立为真(值为 1),不成立为假(值为 0)。
C 语言中,没有表示真假的量,非零即表示真,零表示假。
关系运算符代码说明
代码演示:
#include <stdio.h>
int main()
{
int a = 3; int b = 5;
if (a == b)
{
printf("a == b\n");
}
else
{
printf("a != b\n");
}
printf("express a == b value = %d\n", a == b);
printf("express a != b value = %d\n", a != b);
return 0;
}
运行结果:
逻辑运算符与逻辑表达式
逻辑运算符列表
逻辑运算符说明
首先将运算数值,按逻辑运算进行处理,零为假,非零为真。然后然真值表进行运算。运算的结果也为逻辑的真与假。
&&运算,只要有一个为假,即为假。
||运算,只要有一个为真,即为真。
! 运算,用来取反,优先级要高于其它两个同类型运算符。
逻辑运算,存在短路现象。
&&当两个运算量都是真时,其结果为真。因此,当左边已是 0,右边的表达式不再求解。
|| 当两个运算量有一个为真时,其结果为真。因此,当左边已是 1,右边的表达式不再求解。
短路是一种提升效率的需要。
逻辑运算符代码说明
代码演示:
#include <stdio.h>
int main()
{
int a = 0; int b = 0;
if (a && b)
{
printf("a && b is true\n");
}
else
{
printf("a && b is false\n"); //执行
}
if (a || b)
{
printf("a || b is true\n");
}
else
{
printf("a || b is false\n"); //执行
}
if (!a)
{
printf("!a is true\n"); //执行
}
else
{
printf("!a is false\n");
}
a = 4;
if (a && b)
{
printf("a && b is true\n");
}
else
{
printf("a && b is false\n"); //执行
}
if (a || b)
{
printf("a || b is true\n"); //执行
}
else
{
printf("a || b is false\n");
}
if (!a)
{
printf("!a is true\n");
}
else
{
printf("!a is false\n"); //执行
}
printf("a =% d b = % d\n",a,b);
if ((a < 5) || (b = 3))//注意赋值优先级及短路特点
{
printf("a =% d b = % d\n", a, b); //4 0
}
if( (a > 5) && (b = 3))//注意赋值优先级及短路特点
{
printf("a =% d b = % d\n", a, b); //4 0
}
a = 6;
printf("a =% d b = % d\n", a, b);
if ((a < 5) || (b = 9))//注意赋值优先级及短路特点
{
printf("a =% d b = % d\n", a, b); //6 9
}
if ((a > 5) && (b = 9))//注意赋值优先级及短路特点
{
printf("a =% d b = % d\n", a, b); //6 9
}
return 0;
}
运行结果:
条件运算符与条件表达式
条件运算符列表
条件运算符说明
条件测试部分 test 非零,表达式 exp1 被求值,否则表达式 exp2 被求值,并且保证 exp1 和 exp2 两者之中只有一个被求值。
条件运算符,实际上是一种 if else 结构的简化表达方式。
c 语言致于更简洁。并且支持嵌套。
条件运算符的运算优先级低于关系运算符和算术运算符,但高于赋值符。
条件运算符的结合方向是自右至左(类似于赋值运算符 a= b=c=4)。
条件运算符代码说明
代码演示:
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 4;
printf("%d\n", a > b ? c : d);
printf("%d\n", a < b ? c : d);
printf("%d\n", a > b ? a : c > d ? c : d); // 等价 a>b?a:(c>d?c:d);
printf("%d\n", a > b ? a : c < d ? c : d); // 等价 a>b?a:(c<d?c:d);
printf("%d\n", a < b ? a : c > d ? c : d); // 等价 a<b?a:(c>d?c:d);
printf("%d\n", a < b ? a : c < d ? c : d); // 等价 a<b?a:(c<d?c:d);
return 0;
}
运行结果:
逗号运算符与逗号表达式
逗号运算符列表
逗号运算符说明
逗号运算符,又叫顺序求值运算符。
依次从左到右依次求取各个表达式的值,最后整个逗号表达式的值等于最后一个表达式的值。
逗号表达式支持嵌套。
逗号运算符的优先级最低。
逗号表达式常用于循环结构中。
for(,;;,)
逗号运算符代码说明
代码演示:
#include <stdio.h>
int main()
{
int a;
a = 1, 2, 3, 4, 5, 6;
printf("a = %d\n", a); //1
a = (1, 2, 3, 4, 5, 6);
printf("a = %d\n", a); //6
printf("%d %d %d\n", 1, 2, 3); //1 2 3
printf("%d %d %d\n", (1, 2, 3), 100, 200); //3 100 200
return 0;
}
运行结果:
sizeof 运算符及其表达式
sizeof 运算符列表
sizeof 运算符说明
使用 sizeof 运算符可以获得数据类型占用内存空间的大小。
其一般形式为:
sizeof(type_name)
sizeof(variable_name)。
sizeof 运算符的结果以字节为单位显示。
sizeof 运算符代码说明
代码演示:
#include <stdio.h>
int main()
{
int a;
printf("sizeof(int) = %d\n", sizeof(int));
printf("sizeof(a) = %d\n", sizeof(a));
printf("sizeof a = %d\n", sizeof a);
return 0;
}
运行结果:
注意:
sizeof 本身是一个关键字,是一个运算符,而不是函数。
sizeof 后面可以直接跟变量名,但是不可以直接跟类型名。
小结
()的优先级最高,算术>关系>逻辑>条件>赋值>逗号(并非绝对 (!))。
单目运算符>双目运算符>三目运算符(并非绝对( , = ))
如果不清楚其中的优先级,最好加括号的方式加以强化。