C语言-----操作符的分类
- 人工智能
- 2025-08-23 23:18:01

1. 操作符的分类
•算术操作符: + 、- 、 * 、/、%
移位操作符:<< >>
位操作符: & | ^ `
赋值操作符:= / 、 % 、 += 、-= 、 *=、/=、 %=、 <<=、 >>=、&=、|= 、 ^=
单⽬操作符:!、 ++ 、- 、 & 、 * 、 + 、 、 ~ 、 sizeof 、 ( 类型 )
关系操作符:> 、 >= 、 < 、<= 、 == 、 !=
逻辑操作符:&& 、 ||
• 条件操作符: ? :
• 逗号表达式: ,
• 下标引⽤: []
• 函数调⽤: ()
• 结构成员访问: . 、->
2. ⼆进制和十进制转换2进制
• 2进制中满2进1
• 2进制的数字每⼀位都是0~1的数字组成
比如“1101”
10进制
• 10进制中满10进1
• 10进制的数字每⼀位都是0~9的数字组成
2.1 2进制转10进制10进制的123表⽰的值是⼀百⼆⼗三,为什么是这个值呢?其实10进制的每⼀位是权重的,10进 制的数字从右向左是个位、⼗位、百位....,分别每⼀位的权重是 10 ,10 ,10 ...
举个例子:
比如:二进制1111换为10进制
过程:2^3*1+2^2*1+2^1*1 +2^0*1 将各位的值相加:8 + 4 + 2 + 1 = 15。
二进制数1111转换为十进制数是15。
2.1.1 10进制转2进制数字例如:5的二进制是101
2.2 2进制转8进制和16进制 2.2.1 2进制转8进制16进制的数字每⼀位是0~9,a~f的,0~9,a~f的数字,各⾃写成2进制,最多有4个2进制位就⾜够了, ⽐如f的⼆进制是1111,所以在2进制转16进制数的时候,从2进制序列中右边低位开始向左每4个2进 制位会换算⼀个16进制位,剩余不够4个⼆进制位的直接换算。
如:2进制的01101011,换成16进制:0x6b,16进制表⽰的时候前⾯加0x
3. 原码、反码、补码整数的2进制表示方法有三种,即原码、反码和补码
有符号整数的三种表⽰⽅法均有符号位和数值位两部分,2进制序列中,最⾼位的1位是被当做符号 位,剩余的都是数值位。
符号位都是⽤0表⽰“正”,⽤1表⽰“负”。
10000110 -6
00000110 6
正整数的原、反、补码都相同。
负整数的三种表示方法各不相同。
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
反码得到原码也是可以使用:取反,+1的操作。
转换关系如下图:
4. 移位操作符<< 左移操作符
>> 右移操作符
注: 移位操作符的操作数只能是整数。
4.1 左移操作符<<移位规则:左边抛弃、右边补0
#include <stdio.h> int main() { int num = 10; int n = num<<1; printf("n= %d\n", n); printf("num= %d\n", num); return 0; }上面代码根据移位规则如下图所示:
10二进制1010经过移位变成10100,计算得20
4.2 右移操作符>>移位规则:⾸先右移运算分两种:
1. 逻辑右移:左边⽤0填充,右边丢弃
2. 算术右移:左边⽤原该值的符号位填充,右边丢弃
右移到底是算术右移,还是逻辑右移是取决于编译器的实现,常见的编译器都是算术右移
#include <stdio.h> int main() { int num = -1; int n = num>>1; printf("n= %d\n", n); printf("num= %d\n", num); return 0; }警告⚠:对于移位运算符,不要移动负数位,这个是标准未定义的。
5. 位操作符:&、|、^、~位操作符有:
1 & //按位与 2 | //按位或 3 ^ //按位异或 4 ~ //按位取反注: 他们的操作数必须是整数。
5.1.按位与 & #include <stdio.h> int main() { int a = 3; int b = -5; int c = a & b; //3 //补码:0000 0000 0000 0000 0000 0000 0000 0011 //-5 //原码:1000 0000 0000 0000 0000 0000 0000 0101 //反码:1111 1111 1111 1111 1111 1111 1111 1010 //补码:1111 1111 1111 1111 1111 1111 1111 1011 //计算都是拿补码 //0000 0000 0000 0000 0000 0000 0000 0011 3 //1111 1111 1111 1111 1111 1111 1111 1011 -5 //0000 0000 0000 0000 0000 0000 0000 0011 按位与得到补码 printf("n= %d\n", c); return 0; }如何计算呢,两个补码两个同时唯1才得1,其他为0
5.2.按位或 | #include <stdio.h> int main() { int a = 3; int b = -5; int c = a | b; //3 //补码:0000 0000 0000 0000 0000 0000 0000 0011 //-5 //原码:1000 0000 0000 0000 0000 0000 0000 0101 //反码:1111 1111 1111 1111 1111 1111 1111 1010 //补码:1111 1111 1111 1111 1111 1111 1111 1011 //计算都是拿补码 //0000 0000 0000 0000 0000 0000 0000 0011 3 //1111 1111 1111 1111 1111 1111 1111 1011 -5 //1111 1111 1111 1111 1111 1111 1111 1011 按位或得到补码 //经过计算 //反码:1111 1111 1111 1111 1111 1111 1111 1010 //原码:1000 0000 0000 0000 0000 0000 0000 0101 -5 printf("n= %d\n", c); //打印的是原码 return 0; }如何计算呢,两个补码有一则唯一,两个同时为0才为0
5.3.按位异或 ^ #include <stdio.h> int main() { int a = 3; int b = -5; int c = a ^ b; //3 //补码:0000 0000 0000 0000 0000 0000 0000 0011 //-5 //原码:1000 0000 0000 0000 0000 0000 0000 0101 //反码:1111 1111 1111 1111 1111 1111 1111 1010 //补码:1111 1111 1111 1111 1111 1111 1111 1011 //计算都是拿补码 //0000 0000 0000 0000 0000 0000 0000 0011 3 //1111 1111 1111 1111 1111 1111 1111 1011 -5 //1111 1111 1111 1111 1111 1111 1111 1000 按位异或得到补码 //经过计算 //反码:1000 0000 0000 0000 0000 0000 0000 0111 //原码:1000 0000 0000 0000 0000 0000 0000 1000 -8 printf("n= %d\n", c); return 0; }如何计算呢,两个补码相同为0相异为1
实现值交换:
//a^a 相同为0 //0^a 0和任何数异或为任何数 #include <stdio.h> int main() { int a = 10; int b = 20; a = a ^ b; b = a ^ b;//a ^ b ^ b;b=a a = a ^ b;///a ^ b ^ b;->a ^ b ^ a;a=b printf("a = %d b = %d\n", a, b); return 0; } 5.4.按位取反 ~ #include <stdio.h> int main() { int a = 0; int b = ~a; //0000 0000 0000 0000 0000 0000 0000 0000 //1111 1111 1111 1111 1111 1111 1111 1111 --补码 //1000 0000 0000 0000 0000 0000 0000 0001 补码取反+1变成原码 printf("n= %d\n", b); return 0; }计算一个数二进制数1个数:
#include <stdio.h> int main() { int a = 0; scanf("%d", &a); int count = 0; int i = 0; //原码:0000 0000 0000 0000 0000 0000 0000 1101 13 //原码:0000 0000 0000 0000 0000 0000 0000 0001 1 //由此可以看出任意一个数&1可以得到二进制最后一位是1或0 for (i = 0; i < 32; i++) { if (a & (1 << i)) //1经过左位移操作符,二进制里面一一直往前面移动 { count++; } } printf("%d\n", count); return 0; } 6. 单目操作符单目操作符有这些:
!、++、--、&、*、+、-、~ 、sizeof、(类型)
7. 逗号表达式
1 exp1, exp2, exp3, …expN逗号表达式,就是⽤逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后⼀个表达式的结果。
//代码1 int a = 1; int b = 2; int c = (a>b, a=b+10, a, b=a+1);//逗号表达式 c是多少? 由此得结果:13 //代码2 if (a =b + 1, c=a / 2, d > 0) 逗号表达式从左向右计算,由此起到判断作用是d>0 8. 下标访问[]、函数调用引用() 8.1 []下标操作符操作数:⼀个数组名+⼀个索引值
int arr[10];//创建数组 arr[9] = 10;//实⽤下标引⽤操作符。 [ ]的两个操作数是arr和9。 8.2 函数调用操作符接受⼀个或者多个操作数:第⼀个操作数是函数名,剩余的操作数就是传递给函数的参数
#include <stdio.h> void test1() { printf("hehe\n"); } void test2(const char *str) { printf("%s\n", str); } int main() { test1(); //这⾥的()就是作为函数调⽤操作符。 test2("hello bit.");//这⾥的()就是函数调⽤操作符。 return 0; } 9. 结构成员访问操作符 9.1 结构体C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类 型还是不够的,假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不行的。描述⼀个学生需要 名字、年龄、学号、⾝⾼、体重等;描述⼀本书需要作者、出版社、定价等。C语言为了解决这个问 题,增加了结构体这种自定义的数据类型。
结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如: 标量、数组、指针,甚至是其他结构体。
9.1.1 结构的声明 struct stdunt { char name[20];//名字 int age;//年龄 char sex[5];//性别 char id[20];//学号 };//分号不能丢 9.1.2 结构体变量的定义和初始化 //代码1:变量的定义 struct Point { int x; int y; }p1; //声明类型的同时定义变量p1 struct Point p2; //定义结构体变量p2 //代码2:初始化。 struct Point p3 = {10, 20}; struct Stu //类型声明 { char name[15];//名字 int age; //年龄 }; struct Stu s1 = {"zhangsan", 20};//初始化 struct Stu s2 = {.age=20, .name="lisi"};//指定顺序初始化 //代码3 struct Node { int data; struct Point p; struct Node* next; }n1 = {10, {4,5}, NULL}; //结构体嵌套初始化 struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化 9.2 结构成员访问操作符 9.2.1 结构体成员的直接访问结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。如
下所示:
#include <stdio.h> struct Point { int x; int y; }p = {1,2}; int main() { printf("x: %d y: %d\n", p.x, p.y); return 0; } 使⽤⽅式:结构体变量.成员名 9.2.2 结构体成员的间接访问 有时候我们得到的不是⼀个结构体变量,⽽是得到了⼀个指向结构体的指针。如下所⽰: #include <stdio.h> struct Point { int x; int y; }; int main() { struct Point p = {3, 4}; struct Point *ptr = &p; ptr->x = 10; ptr->y = 20; printf("x = %d y = %d\n", ptr->x, ptr->y); return 0; } 使用⽅式:结构体指针->成员名 10. 操作符的属性:优先级、结合性 C语⾔的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。 10.1 优先级 优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是不⼀样的。 1 3 + 4 * 5; 上⾯⽰例中,表达式 3 + 4 * 5 ⾥⾯既有加法运算符( + ),⼜有乘法运算符( * )。由于乘法 的优先级⾼于加法,所以会先计算 4 * 5 ,⽽不是先计算 3 + 4 。 10.2 结合性 如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符 是左结合,还是右结合,决定执⾏顺序。⼤部分运算符是左结合(从左到右执⾏),少数运算符是右 结合(从右到左执⾏),⽐如赋值运算符( = )。 1 5 * 6 / 2; 上⾯⽰例中, * 和 / 的优先级相同,它们都是左结合运算符,所以从左到右执⾏,先计算 5 * 6 , 再计算 6 / 2 。 来看一下符号优先级:C语言-----操作符的分类由讯客互联人工智能栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C语言-----操作符的分类”
下一篇
欢乐力扣:赎金信