一、运算符与表达式
运算符 就是对字面量或者变量进行操作的符号;表达式 是指用运算符把字面量或者变量连接起来,符合 C语言 语法的式子。不同运算符连接的表达式体现的是不同类型的表达式;
二、算数运算符
数字类型进行运算时,数据类型不一样是不能进行运算的,需要转换成一样的类型,才能运算;当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型(此时的容量大小指的是,表示数的范围的大和小)。
算数运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
+ | 加 | 5 + 2 'a' + 5 |
7 'f' |
- | 减 | 5 - 2 | 3 |
* | 乘 | 5 * 2 | 10 |
/ | 除 | 5 / 2 5.0 / 2 |
2 2.5 |
% | 取模(取余) | 5 % 2 | 1 |
#include <stdio.h>
int main()
{
int a = 5;
int b = 2;
char ch = 'a';
double c = 5;
printf("%d + %d = %d\n",a,b,a+b);
printf("%d - %d = %d\n",a,b,a-b);
printf("%d * %d = %d\n",a,b,a*b);
printf("%d / %d = %d\n",a,b,a/b);
printf("%d %% %d = %d\n",a,b,a%b);
printf("%c + %d = %c\n",ch,a,ch+a);
printf("%lf / %d = %lf\n",c,b,c/b);
return 0;
}
在代码中,如果有小数参与运算,其结果可能是不精确的;
当参与 / 运算的两个操作数都是整数时,表示整数除法;否则,表示浮点除法;
% 取模运算结果的正负与被模数一致,即:a%b 等价于 a-a/b*b,取模结果的正负与 a 的正负一致;
当 字符+字符 或者 字符+数字 的时候,会把字符通过 ASCII码表 查询到对应的数字再进行计算;
三、自增自减运算符
++ 和 -- 即可以放在变量的前面,也可以放在变量的后面;++ 和 -- 无论是放在变量的前面还是后面,单独写一行的结果是一样;如果 前++ 和 前-- 参与运算的话,那 先用后加(减);如果 后++ 和 后-- 参与运算的话,那 先加(减)后用;
自增自减运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
++ | 变量的值加1 | a = 2; b = ++a; a = 2;b = a++; |
a = 3; b = 3; a = 3; b = 2; |
-- | 变量的值减1 | a = 2; b = --a; a = 2; b = a--; |
a = 1; b = 1; a = 1; b = 2; |
#include <stdio.h>
int main()
{
int a = 2;
int b;
// 运算规则等价于 a=a+1; int b=a;
b = ++a;
printf("前++\n");
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
// 运算规则等价于 int b=a; a=a+1;
a = 2;
b = a++;
printf("后++\n");
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
// 运算规则等价于 a=a-1; int b=a;
a = 2;
b = --a;
printf("前--\n");
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
// 运算规则等价于 int b=a; a=a-1;
a = 2;
b = a--;
printf("后--\n");
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
return 0;
}
四、赋值运算符
赋值运算符 用于将表达式的值赋值给变量。
赋值运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
= | 赋值 | a = 10 | 将 10 赋值给变量a |
+= | 加后赋值 | a += b | 将 a + b 的值给 a |
-= | 减后赋值 | a -= b | 将 a - b 的值给 a |
*= | 乘后赋值 | a *= b | 将 a * b 的值给 a |
/= | 除后赋值 | a /= b | 将 a / b 的值给 a |
%= | 取余后赋值 | a %= b | 将 a % b 的值给 a |
<<= | 左移后赋值 | a <<= 3 | 将 a 左移 3 位的值给 a |
>>= | 右移后赋值 | a >>= 3 | 将 a 右移 3 位的值给 a |
&= | 按位与后赋值 | a &= b | 将 a & b 的值给 a |
|= | 按位或后赋值 | a| b | 将 a| b 的值给 a |
^= | 按位异或后赋值 | a ^ b | 将 a ^ b 的值给 a |
#include <stdio.h>
int main()
{
int a = 10;
int b = 10;
a += b;
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
a -= b;
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
a *= b;
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
a /= b;
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
a %= b;
printf("a = %d\n",a);
printf("b = %d\n",b);
putchar('\n');
return 0;
}
五、关系运算符
关系运算符 也被称为 比较运算符;关系运算符 用于表达式的比较,并返回一个真值或假值。在 C语言 中,0 为假,非 0 为真。
关系运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
== | 相等 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 3 | 1 |
#include <stdio.h>
int main()
{
int a = 4;
int b = 3;
printf("%d == %d: %d\n",a,b,(a==b));
printf("%d != %d: %d\n",a,b,(a!=b));
printf("%d < %d: %d\n",a,b,(a<b));
printf("%d <= %d: %d\n",a,b,(a<=b));
printf("%d > %d: %d\n",a,b,(a>b));
printf("%d >= %d: %d\n",a,b,(a>=b));
return 0;
}
六、逻辑运算符
逻辑运算符 用于根据表达式的值返回真值或假值。在 C语言 中,0 为假,非 0 为真。
逻辑运算符 | 功能 |
---|---|
&& | 逻辑与,全真为真,有假为假 |
|| | 逻辑或,有真为真,全假为假 |
! | 逻辑非,非假为真,非真为假 |
运算结果:
a | b | a && b | a|| b | !a |
---|---|---|---|---|
1 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 1 |
0 | 0 | 0 | 0 | 1 |
#include <stdio.h>
int main()
{
int a = 1;
int b = 1;
int c = 0;
int d = 0;
// 逻辑与,两边都为真,结果才为真
printf("%d && %d: %d\n",a,b,(a&&b));
printf("%d && %d: %d\n",a,c,(a&&c));
printf("%d && %d: %d\n",c,d,(c&&d));
printf("\n");
// 逻辑或,两边都为假,结果才为假
printf("%d || %d: %d\n",a,b,(a||b));
printf("%d || %d: %d\n",a,c,(a||c));
printf("%d || %d: %d\n",c,d,(c||d));
printf("\n");
// 逻辑非
printf("!%d: %d\n",a,!a);
printf("!%d: %d\n",c,!c);
printf("\n");
return 0;
}
短路与逻辑运算符 和 逻辑或运算符 具有短路效果,即当左边的表达式能确定最终结果时,那么右边就不会参与运算了;
- 逻辑与运算符;当符号左边是 true 时,&& 会执行右边的运算;当符号左边是 false 时,&& 不再执行符号右边的运算;
- 逻辑或运算符:当符号左边是 false 时,|| 会执行右边的运算;当符号左边是 true 时,|| 不再执行右边的运算;
#include <stdio.h>
int main()
{
// 短路逻辑运算符具有短路效果
// 当左边的表达式能确定最终结果时,那么右边就不会参与运算了
int a = 10;
int b = 10;
int c;
c = (++a < 5) && (++b < 5);
printf("(++a < 5) && (++b <5): %d\n",c);
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("\n");
c = (++a > 5) || (++b > 5);
printf("(++a > 5) || (++b >5): %d\n",c);
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("\n");
return 0;
}
七、位运算符
位运算符是直接对整数的二进制进行的运算; 所有数字在计算机底层都以二进制形式执行;所有的整数值底层都以补码的方式存储;
- 正数:三码合一,符号位为 0;
- 负数:符号位为 1
- 原码:直接将数值转成二进制数,最高位是符号位;
- 反码:对原码按位取反,符号位不变;
- 补码:其反码加 1;
位运算符 | 运算 | 范例 |
---|---|---|
<< | 左移,空位补0,被移除的高位舍弃 | 3 << 2 = 12 |
>> | 右移,空位使用符号位填充,被移除的低位舍弃 | 3 >> 1 = 1 |
& | 与运算,二进制位进行与运算,全1为1,有0为0 | 6 & 3 = 2 |
| | 或运算,二进制位进行或运算,有1为1,全0为0 | 6| 3 = 7 |
^ | 异或运算,二进制位进行异或运算,相同为0,不同为1 | 6 ^ 3 = 5 |
~ | 按位取反,二进制位进行取反运算,非0为1,非1为0 | ~6 = -7 |
#include <stdio.h>
int main()
{
printf("3 << 2: %d\n",(3 << 2));
printf("3 >> 1: %d\n",(3 >> 1));
printf("-3 >> 1: %d\n",(-3 >> 1));
printf("6 & 3: %d\n",(6 & 3));
printf("6 | 3: %d\n",(6 | 3));
printf("6 ^ 3: %d\n",(6 ^ 3));
printf("~6: %d\n",(~6));
return 0;
}
<<:在一定范围内,每向左移一位,相当于乘以2;
>>:在一定范围内,每向右移一位,相当于除以2;
八、三元运算符
- 格式:
(条件表达式) ? 表达式1 : 表达式2;
- 条件表达式的结果为真或为假
- 条件表达式结果为 1,运算后的结果是 表达式1
- 条件表达式结果为 0,运算后的结果是 表达式2
- 表达式1 和 表达式2 为同种类型
- 条件表达式的结果为真或为假
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
// 使用三元运算符获取两个整数的较大值
printf("%d",((a > b) ? a : b));
return 0;
}
三元运算符结果一定要使用,不能单独写在一行;
三元运算符一定可以改成 if-else 语句,反之不成立;
如果程序既可以使用三元运算符又可以使用 if-else 语句,优先使用三元运算符;
九、sizeof运算符
sizeof 运算符用来求字节数长度。
#include <stdio.h>
int main()
{
printf("char: %d\n",sizeof(char));
printf("short: %d\n",sizeof(short));
printf("int: %d\n",sizeof(int));
printf("long: %d\n",sizeof(long));
printf("long long: %d\n",sizeof(long long));
printf("float: %d\n",sizeof(float));
printf("double: %d\n",sizeof(double));
printf("long double: %d\n",sizeof(long double));
return 0;
}
不同的操作系统环境下,使用 sizeof 运算符得到的结果可能不同;
十、运算符的优先级
我们可以使用小括号来提升运算符的优先级;
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
---|---|---|---|---|---|
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | |
() | 圆括号 | ()表达式)/函数名(形参表) | |||
. | 成员选择(对象) | 对象.成员名 | |||
-> | 成员选择(指针) | 对象指针->成员名 | |||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
(类型) | 强制类型转换 | (数据类型)表达式 | |||
++ | 前置自增运算符 | ++变量名 | 单目运算符 | ||
++ | 后置自增运算符 | 变量名++ | 单目运算符 | ||
-- | 前置自减运算符 | --变量名 | 单目运算符 | ||
-- | 后置自减运算符 | 变量名-- | 单目运算符 | ||
* | 取值运算符 | *指针变量 | 单目运算符 | ||
& | 取地址运算符 | &变量名 | 单目运算符 | ||
! | 逻辑非运算符 | !表达式 | 单目运算符 | ||
~ | 按位取反运算符 | ~表达式 | 单目运算符 | ||
sizeof | 长度运算符 | sizeof(表达式) | |||
3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | 双目运算符 | ||
% | 余数(取模) | 整型表达式/整型表达式 | 双目运算符 | ||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | 双目运算符 | ||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | 双目运算符 | ||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | 双目运算符 | ||
< | 小于 | 表达式<表达式 | 双目运算符 | ||
<= | 小于等于 | 表达式<=表达式 | 双目运算符 | ||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!=表达式 | 双目运算符 | ||
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1?表达式2:表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | |
/= | 除后赋值 | 变量/=表达式 | |||
*= | 乘后赋值 | 变量*=表达式 | |||
%= | 取模后赋值 | 变量%=表达式 | |||
+= | 加后赋值 | 变量+=表达式 | |||
-= | 减后赋值 | 变量-=表达式 | |||
<<= | 左移后赋值 | 变量<<=表达式 | |||
>>= | 右移后赋值 | 变量>>=表达式 | |||
&= | 按位与后赋值 | 变量&=表达式 | |||
^= | 按位异或后赋值 | 变量^=表达式 | |||
|= | 按位或后赋值 | 变量|=表达式 | |||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | 从左向右顺序运算 |