文章目录
- 前言
- 运算符优先级顺序表
- 1.算数运算符
- 2.移位运算符
- (1) 左移操作符:
- (2)右移操作符:
- 3.位操作符
- 4.赋值运算符
- 5.单目操作符
- 5.1 介绍
- 5.2 sizeof与数组
- 6.关系操作符
- 7.逻辑操作符
- 8.条件操作符
- 9.逗号表达式
- 10.下标引用、函数调用和结构成员
- 完结
前言
想要学好C语言,操作符是非常重要且必不可少的一部分内容,操作符分为算数运算符、移位操作符、位操作符、赋值操作符、单目操作符、关系操作符、逻辑操作符、条件操作符、逗号表达式、下标引用,函数调用和结构成员。
- 操作符的基本特性
- 每个操作符都有自己的语义
- 每个操作符都有对应的优先级,如果两个操作符挨在一块,先执行优先级高的操作符,如果优先级相同,取决于他们的结合性。
- 每个操作符都有结合性。 操作符的结合性定义了操作符对操作数执行操作的顺序,例如:右结合性表示该操作符对其操作数从右向左执行操作。
运算符优先级顺序表
1.算数运算符
- + – * / %
这是最常见的几个操作符,但还是有一些要注意的点:
(1)对于+、-、*、/来说,如果操作符的两个操作数其中一个操作数是小数,则执行小数运算,如果都为整数,则进行整数运算。
(2)%的两个操作数必须都为整数,否则会报错,其他四个操作符则都可以。
(3)的语言/、%,0不能当除数或者模数 (这应该是个数学问题)。
2.移位运算符
- <> (<>是向右移位)
注意:移位操作符不能移动负数位
(1) 左移操作符:
移位规则:左边抛弃、右边补零。
移位操作符是对操作数的二进制位进行移位,比如对一个int型数据8进行移位的话:
(2)右移操作符:
移位规则:右边抛弃,左边用该值的原符号位填充
右移操作符同理也是对操作数的二进制位向右进行移动,如果是整数,符号位为0,则左面填充0,如果为负数,符号位为1,则左面填充1
3.位操作符
- &(按位与) |(按位或) ^(按位异或) (这些操作符的操作数必须为整数)
位操作符,如同名字一样,也是对操作数的二进制位进行对应的操作
一道小的练习题:
(可以根据上面表格进行运算)
\#include <stdio.h>int main(){int num1 = 1;//二进制00000000 00000000 00000000 00000001int num2 = 2;//二进制00000000 00000000 00000000 00000010num1 & num2;//0num1 | num2;//3num1 ^ num2;//3return 0;}
4.赋值运算符
- =
赋值运算符可以修改一个变量的值,如果你对变量的前一个值不满意可以用=给他赋予一个新的值
int a = 8;int b = 9;float c = 10;char d = 'v';a = b = 10;//还可以连续赋值,不过不建议使用,因为不便于调试
赋值运算符可以与其他运算符结合,变成符合运算符,比如a+=1;就相当于a = a+1;
复合运算符有:+=、-=、*=、/=、%=、>>=、<<=、&=、|=、^=
int a = 0;int b = 8;a+=b;//相当于a = a+b 所有a=8a-=b;//相当于a = a-b因为a=8,a-b为0//其他运算符同理,这种复合运算符可以使代码更加简洁
5.单目操作符
! (逻辑反操作)
– (负值)
+ (正值)
& (取地址)
sizeof (操作数的类型长度(以byte为单位))
~ (对数值的二进制位取反)
– (前置后置- -)
++ (前置后置++)
* (解引用操作符)
(类型) —强制类型转换
- sizeof不关心他的操作数本身是什么,只关心操作数的数据类型
5.1 介绍
演示代码:
#include int main(){int a = -10;int *p = NULL;printf("%d\n", !2);//逻辑反操作,逻辑上一个值不是真就是假,非0即为真,!就是对一个数进行反操作2是真,!2即为假就是0printf("%d\n", !0);//0是假,!0为真,就是1a = -a;//原来的a为-10,-a就是10p = &a;//&就是取a的地址printf("%d\n", sizeof(a));//a的长度就是int类型的长度为4byteprintf("%d\n", sizeof(int));//int的长度为4byteprintf("%d\n", sizeof a);//这样写行不行?//正确,sizeof后面跟变量可以不写括号printf("%d\n", sizeof int);//这样写行不行?//错误,sizeof后面跟数据类型必须加括号return 0;}
//++和--运算符//前置++和--#include int main(){int a = 10;int x = ++a;//先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。x为11。int y = --a;//先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。y为10;return 0;}//后置++和--#include int main(){int a = 10;int x = a++;//先对a先使用,再增加,这样x的值是10;之后a变成11;int y = a--;//先对a先使用,再自减,这样y的值是11;之后a变成10;return 0;}
#includeint main(){a = 10;int* b = &a;printf("%d",b);//在c语言中我们常常会用到指针,如果不对其进行解引用,那么输出的值是a的地址。printf("%d",*b);//解引用后值为10}int main(){float a = 10.3;printf("%d",(int)a);//在实际中如果某个数我们定义成一个类型,但是输出时又想用另一个类型输出,那么我们就可以对其进行强制类型转换,使其强转为你想要的值,但谨慎使用!!!容易出错!!!}
5.2 sizeof与数组
我们都知道一个数组名如果单拿出来是首元素地址,但是对sizeof(),如果里面放一个数组名字,那么这个数组名代表的是整个数组,sizeof(数组名)也就是整个数组的大小。
演示代码:
#include void test1(int arr[]){//这里arr被形参接手之后已经是首地址了,所以sizeof(arr)为8(在64位环境下,32位环境为4)printf("%d\n", sizeof(arr));}void test2(char ch[]){//同上,ch接受过来已经是首地址了,所以地址的大小为8(64位环境下,32位环境为4)printf("%d\n", sizeof(ch));}int main(){int arr[10] = {0};char ch[10] = {0};printf("%d\n", sizeof(arr));//整个数组的大小为40printf("%d\n", sizeof(ch));//整个数组的大小为10test1(arr);test2(ch);return 0;}
6.关系操作符
> >= < <= !=(不等于) ==(等于)
关系运算符就是进行比较,没什么太多细节,结果为真返回1,结果为假返回。
但是有一点需要注意,==和=一定不要看走眼,经常会有题目对这两个操作符进行修改迷惑答题人,=是赋值, ==是等于。
7.逻辑操作符
&&(逻辑与) ||(逻辑或)
- 不要混淆逻辑操作符和位操作符,两者之间有很大区别,一个是对二进制位进行与操作,一个是对数值进行与操作
int main(){printf("%d",1&2);//0,对二进制进行与操作,对应的二进制位都为真,结果为真printf("%d",1&&2);//1,对数值进行与操作,都为真,结果为真printf("%d",1|2);//3,对二进制位进行或操作,对应的二进制位只要有一个为真,结果为真printf("%d",1||2);//1,对数值进行或操作,只要有一方为真,结果为真}
8.条件操作符
exp1 ” />int main{if(a>10)b = 5;elseb =–1; //等价于a>10 ? b=5 : b=–1;}
9.逗号表达式
(exp1, exp2, exp3, …expN)
- 逗号表达式只不过就是用逗号隔开的表达式,从左到右,依次执行,整个表达式的结果为最后一个表达式的结果,注意一定要用括号阔气老。
int main(){int a = 1;int b = 3;int c = (a++,b++,a+b);printf("%d",c);//c = 6 ,从左到右执行返回最右面的表达式//等价于//a++;//b++;//int c = a+b;}
10.下标引用、函数调用和结构成员
[]下标引用操作符 ()函数调用操作符 . 结构体。成员 -> 结构体指针->成员名
1.[ ] 需要两个操作数:数组名 [ 下标值 ]
int arr[10] = {0};//定义数组arr[8] = 8; //用于找到下标
2.()操作数最少要有一个函数名,剩下的操作数看形参的数量 : 函数名(形参1,形参2…)
void test(){printf("asdfa");}void test(int a){printf("%d",a);}int main(){int a=0;test();//一个操作数 testtest(a);//两个操作数 test、a//以此类推还可以有很多操作数,由形参的数量决定}
- . -> 访问结构体的两个操作符
struct Stu{char name[10];int age;};void set_age1(struct Stu stu){stu.age = 18;}void set_age2(struct Stu* pStu){pStu->age = 18;//结构成员访问}int main(){struct Stu stu;struct Stu* pStu = &stu;//结构成员访问stu.age = 20;//结构成员访问set_age1(stu);pStu->age = 20;//结构成员访问set_age2(pStu);return 0;}
完结
创作不易,还请各位小伙伴多多点赞关注✨收藏⭐