【C语言】第二期——运算符与表达式
- IT业界
- 2025-09-03 01:33:02

目录
1 算术运算符
1.1 加减乘除取余
1.2 a++ 与 ++a 的区别
1.3 优先级
2 赋值运算符
2.1 复杂的赋值运算
3 关系运算符
4 逻辑运算符
4.1 逻辑与运算短路
4.2 逻辑或运算符
5 条件运算符(三元运算符)与条件表达式
6 特殊运算符
6.1 求字节数运算符(sizeof)
6.2 强制类型转换运算符
7 进制(位运算符前言)
7.1 C语言进制介绍
7.2 不同进制的表示
7.2.1 二进制
7.2.2 八进制
7.2.3 十六进制
7.3 不同进制的printf占位符
8 位运算符
8.1 按位与、按位或、按位异或
8.2 按位取反 、反码、补码
8.3 移位符
9 优先级
C语言常用的运算符: 算术运算符 赋值运算符 关系运算符 逻辑运算符 条件运算符 类型转换运算符 求字节数运算符 位运算符 ...
1 算术运算符 运算符描述+把两个操作数相加-从第一个操作数中减去第二个操作数*把两个操作数相乘/分子除以分母%取模运算符,整除后的余数++自增运算符,整数值增加 1--自减运算符,整数值减少 11.1 加减乘除取余 //加 #include<stdio.h> int main() { int a = 10; int b = 20; printf("a+b=%d\n", a + b); // 变量相加 printf("a+1=%d\n", a + 1); // 变量与常量相加 printf("1+1=%d\n", 1 + 1); // 常量与常量相加 return 0; }
运行结果: a+b=30
a+1=11
1+1=2
//减 #include <stdio.h> int main() { int a = 10; int b = 20; printf("b-a=%d\n", b - a); // 变量相减 printf("a-1=%d\n", a - 1); // 变量与常量相减 printf("3-1=%d\n", 3 - 1); // 常量与常量相减 return 0; }运行结果:
b-a=10
a-1=9
3-1=2
//乘 #include <stdio.h> int main() { int a = 10; int b = 20; printf("b*a=%d\n", b * a); // 变量相乘 printf("a*1=%d\n", a * 1); // 变量与常量相乘 printf("3*1=%d\n", 3 * 1); // 常量与常量相乘 return 0; }运行结果:
b*a=200
a*1=10
3*1=3
//除 #include<stdio.h> int main() { int a = 10; int b = 20; printf("b/a =%d\n", b / a); printf("a/1 =%d\n", a / 1); printf("20/10=%d\n", 20 / 10); printf("b/6 =%d\n", b / 6); printf("b/6.0 =%lf\n", b / 6.0); printf("20/6 =%d\n", 20 / 6); printf("20/6.0=%lf\n", 20 / 6.0); return 0; }运行结果:
b/a =2
a/1 =10
20/10=2
b/6 =3
b/6.0 =3.333333
20/6 =3
20/6.0=3.333333
//取余 #include <stdio.h> int main() { int a = 6; int b = 20; printf("%d\n", b % a); printf("%d\n", a % 5); printf("%d\n", 20 % 3); printf("%d\n", 20 % 4); return 0; }运行结果:
2
1
2
0
1.2 a++ 与 ++a 的区别 #include <stdio.h> int main() { printf("先赋值后运算:\n"); int c; int a = 10; c = a++; printf("Line 1 - c 的值是 %d\n", c ); printf("Line 2 - a 的值是 %d\n", a ); a = 10; c = a--; printf("Line 3 - c 的值是 %d\n", c ); printf("Line 4 - a 的值是 %d\n", a ); //—————————————————————————————————————————————————————————————— printf("先运算后赋值:\n"); a = 10; c = ++a; printf("Line 5 - c 的值是 %d\n", c ); printf("Line 6 - a 的值是 %d\n", a ); a = 10; c = --a; printf("Line 7 - c 的值是 %d\n", c ); printf("Line 8 - a 的值是 %d\n", a ); }
运行结果: 先赋值后运算:
Line 1 - c 的值是 10
Line 2 - a 的值是 11
Line 3 - c 的值是 10
Line 4 - a 的值是 9
先运算后赋值:
Line 5 - c 的值是 11
Line 6 - a 的值是 11
Line 7 - c 的值是 9
Line 8 - a 的值是 9
1.3 优先级
当算术表达式由多个不同的算术运算符组成时,会按照运算符的优先级进行运算:
先乘除后加减、先括号里再括号外,
优先级相同,按照自左向右的顺序进行运算
分析:a*10+(100%3)-b/10 的值
#include <stdio.h> int main() { int a = 12; int b = 100; printf("%d", a * 10 + (100 % 3) - b / 10); }2 赋值运算符 运算符描述实例=简单的赋值运算符,把右边操作数的值赋给左边操作数C = A + B 将把 A + B 的值赋给 C+=加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数C += A 相当于 C = C + A-=减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数C -= A 相当于 C = C - A*=乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数C *= A 相当于 C = C * A/=除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数C /= A 相当于 C = C / A%=求模且赋值运算符,求两个操作数的模赋值给左边操作数C %= A 相当于 C = C % A
可以运行一下以下代码:
#include<stdio.h> int main() { int a; int b; int c; a = 20; // 将数值 20 赋值给变量 a b = a - 10; // 先计算 a-10,然后将计算结果赋值给变量 b c = a + b; // 先计算 a+b,然后将计算结果赋值给变量 c printf("a=%d\n", a); printf("b=%d\n", b); printf("c=%d\n", c); return 0; } #include <stdio.h> int main() { int a = 21; int c; c = a; printf("Line 1 - = 运算符实例,c 的值 = %d\n", c); c += a; printf("Line 2 - += 运算符实例,c 的值 = %d\n", c); c -= a; printf("Line 3 - -= 运算符实例,c 的值 = %d\n", c); c *= a; printf("Line 4 - *= 运算符实例,c 的值 = %d\n", c); c /= a; printf("Line 5 - /= 运算符实例,c 的值 = %d\n", c); c = 200; c %= a; printf("Line 6 - %%= 运算符实例,c 的值 = %d\n", c); }2.1 复杂的赋值运算 #include<stdio.h> int main() { int a = 1; int b = 2; a += b * 20; b %= a + 10; printf("a=%d\n", a); printf("b=%d\n", b); return 0; }
运行结果: a=41
b=2
3 关系运算符
关系运行符中输出1表示真,输出0表示假。
运算符描述实例==检查两个操作数的值是否相等,如果相等则条件为真。(A == B) 为假!=检查两个操作数的值是否相等,如果不相等则条件为真。(A != B) 为真>检查左操作数的值是否大于右操作数的值,如果是则条件为真。(A> B) 为假<检查左操作数的值是否小于右操作数的值,如果是则条件为真。(A < B) 为真>=检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。(A>= B) 为假<=检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。(A <= B) 为真 #include <stdio.h> int main() { int a = 10; int b = 20; int c = 30; printf("%d\n", 1 > 2); printf("%d\n", 5 >= 2); printf("%d\n", a < 2); printf("%d\n", a <= b); printf("%d\n", a + b == c); printf("%d\n", c != a + b); return 0; }运行结果: 0
1
0
1
1
0
4 逻辑运算符 运算符描述实例&&称为逻辑与运算符。如果两个操作数都非零,则条件为真。(A && B) 为假||称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。(A || B) 为真!称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。!(A && B) 为真 #include<stdio.h> int main() { int gender = 1; // gender 性别: 1 表示男, 0 表示女 int adult = 1; // adult 是否成年: 1 表示成年, 0 表示未成年 printf("%d\n", gender && adult); printf("%d\n", gender || adult); printf("%d\n", !gender); printf("%d\n", !adult); getchar(); return 0; } #include <stdio.h> int main() { int a = 5; int b = 20; printf("%d\n", a && b); printf("%d\n", a || b); printf("%d\n", !a); }
4.1 逻辑与运算短路
当“&&”左侧为“假”时,逻辑与运算表达式结果直接为“假”,“&&”右侧将不再进行判断
#include <stdio.h> int main() { int a = 8; int b = (a > 5) && ((a = a + 5) < 10); printf("b=%d\n", b); printf("a=%d", a); return 0; }运行结果:
b=0
a=13
#include <stdio.h> int main() { int a = 8; int b = (a < 5) && ((a = a + 5) < 10); printf("b=%d\n", b); printf("a=%d", a); return 0; }运行结果:
b=0
a=8
4.2 逻辑或运算符
当“||”左侧为“真”时,逻辑或运算表达式结果直接为“真”,“||”右侧将不再进行判断
#include <stdio.h> int main() { int a = 8; int b = (a < 5) || ((a = a + 5) < 10); printf("b=%d\n", b); printf("a=%d", a); return 0; }运行结果:
b=0
a=13
#include <stdio.h> int main() { int a = 8; int b = (a > 5) || ((a = a + 5) < 10); printf("b=%d\n", b); printf("a=%d", a); return 0; }运行结果:
b=1
a=8
5 条件运算符(三元运算符)与条件表达式
条件运算符又被称为三元运算符,是C语言中唯一的一个三元运算符,基本格式如下:
表达式1 ? 表达式2 : 表达式3 max = a>b ? a : b其求值规则为:如果表达式1的值为真,则以表达式2 的值作为整个条件表达式的值,否则以表达式3的 值作为整个条件表达式的值。条件表达式通常用于赋值语句之中。
#include <stdio.h> int main() { int a = 9; nt b = 0; b = (a > 10 ? 888 : 666); printf("b=%d\n", b); b = (a > 5 ? 888 : 666); printf("b=%d\n", b); return 0; }6 特殊运算符 6.1 求字节数运算符(sizeof)
c语言中,使用sizeof运算符可以获取一个数据类型或者一组数据类型的字节数。
例如,sizeof(int)会返回4,因为int类型通常占据4个字节。
#include<stdio.h> int main() { printf("sizeof(char) =%d\n", sizeof(char)); printf("sizeof(int) =%d\n", sizeof(int)); printf("sizeof(float) =%d\n", sizeof(float)); printf("sizeof(double)=%d\n", sizeof(double)); return 0; }运行结果:
sizeof(char) =1
sizeof(int) =4
sizeof(float) =4
sizeof(double)=8
6.2 强制类型转换运算符
强制类型转换运算符由括号“( )“和数据类型两部分构成,形为:(数据类型)
其一般使用形式为:
(数据类型)常量; (数据类型)变量; (数据类型)(表达式);其作用是将常量、变量、表达式运算结果等,转换为括号中的指定数据类型
#include <stdio.h> int main() { int a; float f; a = (int)3.14; f = (float)(10 + 20); printf("a=%d\n", a); printf("f=%f\n", f); return 0; }运行结果:
a=3 f=30.000000
7 进制(位运算符前言)
位运算符通常用于进行二进制操作
在了解位运算符前我们首先需要知道什么是10进制、2进制 、16进制
7.1 C语言进制介绍对于计算机来说,本质上只能识别和执行0和1组成的二进制指令,例如:
0101 1111 0000 0000
在嵌入式系统开发中,16进制和二进制通常用于将数据转换为易于处理的形式。
例如,在嵌入式系统中使用16进制可以更容易地处理数据和变量,因为大多数硬件都支持16进制。
同样,二进制是嵌入式系统中最常用的编码方式之一,因为它可以轻松地与CPU指令集配合使用,并且可以更好地控制内存访问等操作 。
十进制二进制十六进制十进制二进制十六进制000000810008100011910019200102101010A300113111011B401004121100C501015131101D601106141110E701117151111F我们都知道10进制逢10进1
同理:
二进制是逢2进1,一般我们用四位为一组表示一个二进制数
16进制是逢16进1,一般嵌入式中我们用一个16进制数表示一组二进制数
7.2 不同进制的表示 7.2.1 二进制
二进制由 0 和 1 两个数字组成,使用时必须以0b或0B(不区分大小写)开头
例如:
//合法的二进制 int a = 0b101; //换算成十进制为 5 int b = -0b110010; //换算成十进制为 -50 int c = 0B100001; //换算成十进制为 33 //非法的二进制 int m = 101010; //无前缀 0B,相当于十进制 int n = 0B410; //4不是有效的二进制数字注意:标准的C语言并不支持上面的二进制写法,只是有些编译器自己进行了扩展,才支持二进制数字。换句话说,并不是所有的编译器都支持二进制数字,只有一部分编译器支持,并且跟编译器的版本有关系。
7.2.2 八进制
八进制由 0~7 八个数字组成,使用时必须以0开头
//合法的八进制数 int a = 015; //换算成十进制为 13 int b = -0101; //换算成十进制为 -65 int c = 0177777; //换算成十进制为 65535 //非法的八进制 int m = 256; //无前缀 0,相当于十进制 int n = 03A2; //A不是有效的八进制数字7.2.3 十六进制
十六进制由数字 0~9、字母 A~F 或 a~f(不区分大小写)组成,使用时必须以 0x 或 0X(不区分大小写)开头
例如:
//合法的十六进 int a = 0X2A; //换算成十进制为 42 int b = -0XA0; //换算成十进制为 -160 int c = 0xffff; //换算成十进制为 65535 //非法的十六进制 int m = 5A; //没有前缀 0X,是一个无效数字 int n = 0X3H; //H不是有效的十六进制数字7.3 不同进制的printf占位符
%d 可以以十进制输出整数、%o可以以八进制输出整数、%X可以以16进制输出整数
%x和%X这两个占位符中x的大小写会决定输出十六进制数时字母部分的大小写
#include <stdio.h> #include <stdlib.h> int main() { int a = 12; printf("八进制 --> %o\n", a); printf("十六进制 --> %X\n", a); printf("十进制 --> %d\n", a); char s[16]; itoa(a, s, 2); printf("二进制 --> %s\n", s); return 0; }8 位运算符 运算符描述&按位与:对两个操作数的每一位执行逻辑与操作,如果两个相应的位都为 1,则结果为 1,否则为 0。按位与操作,按二进制位进行 “与” 运算。运算规则:0 & 0 = 0; 0 & 1 = 0; 1 & 0 = 0; 1 & 1 = 1;|按位或:对两个操作数的每一位执行逻辑或操作,如果两个相应的位都为 0,则结果为 0,否则为 1。按位或运算符,按二进制位进行 “或” 运算。运算规则:0 | 0 = 0; 0 | 1 = 1; 1 | 0 = 1;1 | 1 = 1;^按位异或:对两个操作数的每一位执行逻辑异或操作,如果两个相应的位值相同,则结果为 0,否则为 1。异或运算符,按二进制位进行 “异或” 运算。运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0;~按位取反:对操作数的每一位执行逻辑取反操作,即将每一位的 0 变为 1,1 变为 0。取反运算符,按二进制位进行 “取反” 运算。运算规则:~1=-2; ~0=-1;(详看补码系统)<<按位左移:将操作数的所有位向左移动指定的位数。左移 n 位相当于乘以 2 的 n 次方。二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补 0)。>>按位右移:将操作数的所有位向右移动指定的位数。右移 n 位相当于除以 2 的 n 次方。二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补 0,负数左补 1,右边丢弃。
8.1 按位与、按位或、按位异或 #include <stdio.h> #include <stdlib.h> int main() { char a = 0b00000001; // 相当于10进制1 char b = 0b00001001; // 相当于10进制9 printf("a对应的10进制%d\n", a); printf("b对应的10进制%d\n", b); // 00000001 & 00001001=00000001 如果两个相应的位都为 1,则结果为 1 printf("a&b 按位与值%d\n", a & b); // 00000001 & 00001001=00001001 如果两个相应的位都为 0,则结果为 0 printf("a|b 按位或的值%d\n", a | b); // 00000001 ^ 00001001=00001000 如果两个相应的位值相同,则结果为 0 printf("a^b 按位异或的值%d\n", a ^ b); }
8.2 按位取反 、反码、补码
对操作数的每一位执行逻辑取反操作,即将每一位的 0 变为 1,1 变为 0
如 0 000 0001 按照位取反后得到的二进制位 1111 1110
如 0 000 1001 按照位取反后得到的二进制位 1111 0110
#include <stdio.h> #include <stdlib.h> int main() { char a = 0b00000001; // 相当于10进制1 printf("a按位取反的十进制值是%d\n", ~a); char b = 0b00001001; // 相当于10进制9 printf("b按位取反的十进制值是%d", ~b); }输出结果为: a按位取反的十进制值是-2
b按位取反的十进制值是-10
问题: 这个结果和我们上面想要的结果出入很大,为什么呢?
原因:在计算机中数据是以其补码形式存储和运算的 。
首先补充几个概念:
机器数:数值在计算机中的二进制表示形式,机器数通常使用最高位作为符号位,一般规定 0 表示正数,1 表示负数
真值:一个数在数学中的实际数值
原码:一种最简单的机器数表示法。最高位为符号位,其余位表示数值的绝对值。符号位用 0 表示正数,用 1 表示负数。(可进行无符号计算)
反码:反码的符号位与原码相同,正数的反码和原码相同;负数的反码是在原码的基础上,符号位不变,其余各位按位取反。(可参与符号计算,但会出现-0的情况,即11111111)
补码:正数的补码和原码、反码相同;负数的补码是在其反码的基础上加 1。补码解决了原码在加减法运算中的问题,使得计算机可以使用加法器统一进行加法和减法运算。
(可参与符号计算,排除了-0的情况)
在上文代码中,a变量存储的值0000 0001首位为0,为正数,所以其反码补码都是0000 0001
我们提到,在计算机中数据是以补码形式参与计算的,所以在其参与计算(取反计算)后,得到的数还是补码 1111 1110 ,
最终我们是让其以十进制打印出结果,即打印真值,而此时还是补码,因此我们要将补码转成原码(因为原码可以直观转化为真值)
操作为原码转补码的逆运算:
第一步:1111 1110先减一,得到1111 1101(此时为反码)
第二步:再将其除了符号位都取反,即 1000 0010(此时为原码)
第三步:原码即可转化为真值
1000 0010,首位为1,为负数,剩下七位转成十进制为2,所以最终显示-2
注意:补码先加一再取反效果与上述一样,但不便于理解,不推荐
视频教程:
【一听就懂】C语言必会之原码/反码/补码!分析+实例,十分钟带你彻底掌握,这可比学校讲的细致多了!_哔哩哔哩_bilibili
8.3 移位符
<< 按位左移:
将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)
>> 按位右移:
将一个数的各二进制位全部右移若干位
注意所移动的值最高位是否表示符号,以及移动过后正负性的改变
#include <stdio.h> int main() { char a = 0b00001000; // 0000 1000 左移2位0010 0000 printf("a按位左移2位后的的十进制值是%d\n", a << 2); // 0000 1000 右移动2位 0000 0010 }9 优先级
下表将按运算符优先级从高到低列出各个运算符
(具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面)
在表达式中,较高优先级的运算符会优先被计算
表格里的 “结合性” 指的是当一个表达式中有多个相同的运算符时,运算执行的方向
类别运算符结合性后缀() [] ->. ++ --从左到右一元+ -! ~ ++ -- (type)* & sizeof从右到左乘除* / %从左到右加减+ -从左到右移位<< >>从左到右关系< <= > >=从左到右相等== !=从左到右位与 AND&无位异或 XOR^无位或 OR**无逻辑与 AND&&无逻辑或 OR||无条件?:从右到左赋值= += -= *= /= %= >>= <<= &= ^= |=从右到左逗号,无【C语言】第二期——运算符与表达式由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【C语言】第二期——运算符与表达式”
上一篇
【C++算法竞赛函数速查表】
下一篇
PMBOK第7版整体架构全面详解