目录
- 一、操作符的分类
- 二、算术操作符
- 三、 移位操作符
- 3.1<<左移操作符
- 3.1.1移位规则
- 3.1.2直接上代码以及解释
- 3.2>> 右移操作符
- 3.2.1移位规则
- 3.2.2画图解释
- 3.3注意
- 四、位操作符:&、|、^、~
- 4.1&按位与
- 4.1.1按位与的计算逻辑
- 4.1.2代码
- 4.1.3运行结果
- 4.1.4 画图解释
- 4.2 按位或(|)
- 4.2.1按位或的计算逻辑
- 4.2.2 代码
- 4.2.3运行结果
- 4.2.4画图解释
- 4.3按位异或(^)
- 4.3.1按位异或计算逻辑
- 4.3.2代码
- 4.3.3 运算结果
- 4.3.4画图解释
- 4.4按位取反(~)
- 4.4.1按位取反计算逻辑
- 4.4.2代码
- 4.4.3运行结果
- 4.4.4画图分析
- 五、单目操作符
- !、++、--、&、*、+、-、~ 、(类型)
- 六、逗号表达式
- 6.1形式
- 6.2特点
- 6.3代码
- 6.4运行结果
- 6.5画图解释
- 七、 下标访问[]、函数调用()
- 7.1下标访问[]操作符
- 7.2函数调用操作符
- 八、结构成员访问操作符
- 8.1结构体
- 8.1.1结构的声明
- 8.1.2结构体变量的定义和初始化
- 8.1.3 结构体成员的直接访问
- 8.1.3.1代码1
- 8.1.3.1.1代码1运行结果
- 8.1.3.2代码2
- 8.1.3.2.2代码2运行结果
- 8.1.4接构体成员的间接访问
- 8.1.4.1代码
- 8.1.4.1.1代码运行结果:
- 九、 操作符的属性:优先级、结合性
- 9.1优先级
- 9.2结合性
- 9.3注意
- 十、 总结
一、操作符的分类
算术操作符: + 、- 、*、/ 、%
移位操作符: << >>
位操作符: & | ^ `
赋值操作符: = 、+= 、 -= 、 = 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^=
单⽬操作符: !、++、–、&、、+、-、~ 、sizeof、(类型)
关系操作符: > 、>= 、< 、<= 、 == 、 !=
逻辑操作符: && 、||
条件操作符: ? :
逗号表达式: ,
下标引⽤: []
函数调⽤: ()
结构成员访问: . 、->
二、算术操作符
三、 移位操作符
3.1<<左移操作符
3.1.1移位规则
左边抛弃,右边补0。
3.1.2直接上代码以及解释
#include<stdio.h>
int main()
{int a = 6;int b = a << 1;printf("%d\n", a);printf("%d\n", b);return 0;
}
运行结果:
数据存放内存中其实存放的是补码。
如果改成a=-6,那么结果如何呢?
直接上代码:
#include<stdio.h>
int main()
{int a = -6;int b = a << 1;printf("%d\n", a);printf("%d\n", b);return 0;
}
运行结果:
3.2>> 右移操作符
3.2.1移位规则
首先右移运算分两种:
1.逻辑右移:左边用0填充,右边丢弃。
2.算术右移:左边用原该值的符号位填充,右边丢弃。
其次右移到底是算术右移,还是逻辑右移取决于编译器的实现,常见的编译器都是算术右移。
3.2.2画图解释
3.3注意
1.移位操作符的操作数只能是整数,移动的是二进制。
2.不要移动负数位,这是未定义的,例如:
int num = 10;
num>>-1;//error
四、位操作符:&、|、^、~
操作的是二进制位。
& //按位与
|//按位或
^//按位异或
~//按位取反
4.1&按位与
4.1.1按位与的计算逻辑
相同为1,不同为0。
4.1.2代码
#include<stdio.h>
int main()
{int a = 3;int b = -5;int c = a & b;printf("%d\n", c);return 0;
}
4.1.3运行结果
4.1.4 画图解释
4.2 按位或(|)
4.2.1按位或的计算逻辑
两个同时为0,才为0
4.2.2 代码
#include<stdio.h>
int main()
{int a = 3;int b = -5;int c = a |b;printf("%d\n", c);return 0;
}
4.2.3运行结果
4.2.4画图解释
4.3按位异或(^)
4.3.1按位异或计算逻辑
相同为0,相异为1。
4.3.2代码
#include<stdio.h>
int main()
{int a = 3;int b = -5;int c = a ^b;printf("%d\n", c);return 0;
}
4.3.3 运算结果
4.3.4画图解释
4.4按位取反(~)
4.4.1按位取反计算逻辑
所有位按位取反
4.4.2代码
#include<stdio.h>
int main()
{int a = 0;int b= ~a;printf("%d\n", b);return 0;
}
4.4.3运行结果
4.4.4画图分析
五、单目操作符
!、++、–、&、*、+、-、~ 、(类型)
如上图标黄色的,先参与运算,再加或减。
如上图标红色的,先加或减,再运算。
六、逗号表达式
逗号表达式,就是⽤逗号隔开的多个表达式。
6.1形式
exp1, exp2, exp3, …expN
6.2特点
从左往右依次计算,取最右边的结果为表达式最后的结果。
6.3代码
#include<stdio.h>
int main()
{int a = 1;int b = 2;int c = (a > b, a = b + 10, a, b = a + 1);printf("%d", c);return 0;
}
6.4运行结果
6.5画图解释
七、 下标访问[]、函数调用()
7.1下标访问[]操作符
#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5 };printf("%d", arr[2]);//这里的[]就是下标访问操作符return 0;
}
7.2函数调用操作符
八、结构成员访问操作符
8.1结构体
c语⾔已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的,假设我想描述学⽣,描述⼀本书,这时单⼀的内置类型是不⾏的。描述⼀个学⽣需要名字、年龄、学号、⾝⾼、体重等;描述⼀本书需要作者、出版社、定价等。C语⾔为了解决这个问题,增加了结构体这种⾃定义的数据类型,让程序员可以⾃⼰创造适合的类型。结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:标量、数组、指针,甚⾄是其他结构体。
8.1.1结构的声明
创造一个新的类型
struct tag
{member-list;
}variable-list;
描述一个学生:
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}s4,s5,s6; //分号不能丢
//s4,s5,s6是结构体变量(全局的)
struct Stu s7;//也是全局的
int main()
{struct Stu s1;struct Stu s2;struct Stu s3;//s1,s2,s3这三个结构体变量(局部的)return 0;
}
8.1.2结构体变量的定义和初始化
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}s4, s5, s6; //分号不能丢
//s4,s5,s6是结构体变量(全局的)
struct Stu s7;//也是全局的
int main()
{struct Stu s1 = { "张三",20,"男","20231234" };//初始化struct Stu s2={.age=30,.name="Lina", .sex="男",.id="1008611"};//指定顺序初始化struct Stu s3;//s1,s2,s3这三个结构体变量(局部的)return 0;
}
再看一个初始化
#include<stdio.h>struct S
{char c;int n;
};
struct B
{struct S s;int* p;char arr[10];float sc;
};
int main()
{struct B b = { {'A',60},NULL,"权权",66.6f };//初始化breturn 0;
}
8.1.3 结构体成员的直接访问
使用方式:结构体变量.成员名
8.1.3.1代码1
#include<stdio.h>
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}s4, s5, s6; //分号不能丢
//s4,s5,s6是结构体变量(全局的)
struct Stu s7;//也是全局的
int main()
{struct Stu s1 = { "张三",20,"男","20231234" };//初始化struct Stu s2={.age=30,.name="Lina", .sex="男",.id="1008611"};//指定顺序初始化struct Stu s3;//s1,s2,s3这三个结构体变量(局部的)printf("%s %d %s %s", s1.name, s1.age, s1.sex, s1.id);return 0;
}
8.1.3.1.1代码1运行结果
8.1.3.2代码2
#include<stdio.h>
struct S
{char c;int n;
};
struct B
{struct S s;int* p;char arr[10];float sc;
};
int main()
{struct B b = { {'A',60},NULL,"权权",66.6f };printf("%c\n", b.s.c);return 0;
}
8.1.3.2.2代码2运行结果
8.1.4接构体成员的间接访问
使用方法:结构体指针->成员名
有时候我们得到的不是⼀个结构体变量,⽽是得到了⼀个指向结构体的指针。如下所示:
8.1.4.1代码
#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;
}
8.1.4.1.1代码运行结果:
九、 操作符的属性:优先级、结合性
C语⾔的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。
9.1优先级
优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是不⼀样的。
3 + 4 * 5;
上面示例中,表达式 3 + 4 * 5 里面既有加法运算符( + ),又有乘法运算符( * )。由于乘法的优先级高于加法,所以会先计算 4 * 5 ,而不是先计算 3 + 4 。
9.2结合性
如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执⾏顺序。⼤部分运算符是左结合(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符( = )。
5* 6 / 2;
上面示例中, * 和 / 的优先级相同,它们都是左结合运算符,所以从左到右执行,先计算 5 * 6 ,再计算 6 / 2 。
运算符的优先级顺序很多,下面是部分运算符的优先级顺序(按照优先级从⾼到低排列),建议大概记住这些操作符的优先级就行,其他操作符在使用的时候查看下面表格就可以了。
• 圆括号( () )
• 自增运算符( ++ ),⾃减运算符( – )
• 单⽬运算符( + 和 - )
• 乘法( * ),除法( / )
• 加法( + ),减法( - )
• 关系运算符( < 、 > 等)
• 赋值运算符( = )
由于圆括号的优先级最⾼,可以使用他改变其他运算符的优先级。
下表列出 C 运算符的优先级和结合性。运算符从上到下以降序列出。
9.3注意
即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯⼀的计算路径,那这个表达式就是存在潜在⻛险的,建议不要写出特别负责的表达式。
十、 总结
掌握好操作符,可以更好的在编程中得心应手,虽然有一点多,加油,奥利给,干就完了。
欧耶!!!!!我学会啦!!!!!