操作符分类
操作符可以分为:
算数操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号操作符
下表引用、函数调用和结构成员
(一)算数操作符:
加(+) 减(-) 乘 (*)除(/ ) 取模(%)
要注意的一点,整数乘除法运算只能得到整数
(二)移位操作符
int a =16;
//>> 右移操作符
//移动的是二进制位
int b =a>>1;
右移操作符:
1.算数右移
右边丢弃,左边补原符号位
2.逻辑右移
右边丢弃,左边补0
警告:
对于移位运算符,不要移动负数位。这个是标准定义的,什么意思呢,举个栗子:
int main =10;
num>>-1;//error
(三)位操作符
1) ‘&’ 按照二进制位与,全为1结果才为1,否则为0。
int main()
{
//& 按二进制位与
int a = 3;
int b =5;
int c =a&b;
//00000000 00000000 00000000 00000011
//00000000 00000000 00000000 00000101
//00000000 00000000 00000000 00000001
printf("%d\n",c);
return 0;
}
可能你会问,为什么01存在了最前面,而不是我们写的那样的顺序存储?
这就涉及到计算机的大端存储与小端存储,我会在后面博客讲述该内容,这里我们只需要知道按位与是如何工作的就可以了。
2)‘|’ 按二进制或,全0为0,否则为1。‘|’和‘&’是对冤家,两个反着来的。
//按二进制位或
int main()
{
int a = 3;
int b = 5;
int c = a|b;
//00000000 00000000 00000000 00000011
//00000000 00000000 00000000 00000101
//00000000 00000000 00000000 00000111
return 0;
}
3)‘^’按2进制位异或,相同为0,相异为1。
int main()
{
//按二进制位异或
//相同为0,相异为1
int a =3;
int b =5;
int c =a^b;
printf("%d\n",c);
//00000000 00000000 00000000 00000011
//00000000 00000000 00000000 00000101
//00000000 00000000 00000000 00000110
return 0;
}
4)‘~’按二进制位取反
1变成0,0变成1。青春期有些小叛逆。
拓展:你知道怎么求二进制位中有几个1吗?
int main()
{
int num = 0;
int count = 0;
scanf("%d",&num);//3
//统计num的补码中有几个1
while(num)
{
if (num %2 == 1)
count++;
num = num/2;
}
printf("%d\n",count);
return 0;
}
5)复合位操作符
int main()
{
int a =11;
a = a |(1<<2);
printf("%d\n",a);//输出15
a =a & (~(1<<2));
printf("%d\n",a));//输出11
return 0;
}
(四)(复合)赋值符
±
-=
*=
/=
%=
=
<<=
&=
|=
^=
举栗子:
32位操作系统
//short int 2字符 int 4字符
int main()
{
short s = 0;
int a = 10;
//sizeof是计算占字节大小的,长度运算符,也是
//单目操作符
printf("%d\n", sizeof(s = a + 5));//输出2
printf("%d\n", s);//输出0
return 0;
}
为什么s输出的0呢?
因为sizeof括号里面的不直接运算,也就是输出的s还是0.
1)前置++ 与后置++的区别
前置++,先加厚使用,后置++,先使用后++。看栗子:
int main()
{
int a =10;
//printf("%d\n",++a);//输出11
printf("%d\n",a++);//输出10
return 0;
}
2)强制类型转换(类型),注意:给类型加括号
int main()
{
int a = (int)3.14;
return 0;
}
(五)关系操作符
>= < <= != ==
这个就很简单了,大家应该都是知道的
(六)逻辑操作符
&&逻辑与
|| 逻辑或
!逻辑非
(七)条件操作符
exp? exp:exp
栗子
int main()
{
int a = 0;
int b = 0;
if (a>5)
b=3;
else
b =-3;
//b =(a>5? 3:-3);效果与上面if语句类似
return 0;
}
(八)逗号操作符(很容易搞错的地方,一定要引起重视)
代码1输出结果为b(最后一个),代码2d>0为条件
//代码1
int a =1;
int b = 2;
int c =(a>b,a=a+10,a,b =a+1);
//c是多少
//代码2
if(a =b +1,c = a/2,d>0)
(九)结构体
struct Stu
{
char name[10];
int age;
char id[20];
};
int main()
{
int a = 10;
//使用struct Stu这个类型创建了一个学生对象s1,并初始化
struct Stu s1 = { "张三",20,"202110305" };
struct Stu* ps =&s1;
printf("%s\n", ps->name);
printf("%d\n", ps->age);
//结构体指针->成员名
//相当于
printf("%s\n", (*ps).name);//这里括号不能省
printf("%d\n", (*ps).age);
//或者
printf("%s\n", s1.name);
printf("%d\n", s1.age);
}
拓展:整形提升
c的整形算数运算符总是至少以缺省整形类型的精度来进行的。
什么意思呢?
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换就叫做整型提升。
看例子:
int main()
{
char a = 3;
//00000000 00000000 00000000 00000011
//00000011 a
char b = 127;
//00000000 00000000 00000000 01111111
//01111111 a
// a和b如何相加
//00000000 00000000 00000000 00000011
//00000000 00000000 00000000 01111111
//00000000 00000000 00000000 10000010
char c = a + b;
//1000010 c
//11111111 11111111 11111111 10000010 补码
//11111111 11111111 11111111 10000001 反码
//10000000 00000000 00000000 01111110 原码
//-126
printf("%d\n", c);
return 0;
}
//看下面这个例子`
只会输出c、a、b(16进制)运算会发生整形提升,值会变化。
int main()
{
char a =0xb6;//11111111 11111111 11111111 1011 0110
//11111111 11111111 11111111 1011 0101
//10000000 00000000 00000000 0100 1010
//0x4A
short b =0xb600;
int c = 0xb6000000;
if(a==0xb6)
{
printf("a");
}
if(b==0xb600)
{
printf("b");
}
if(c==0xb6000000)
{
printf("c");
}
return 0;
}