目录
一、操作符分类
二 、算术操作符
三、移位操作符
补充:二进制
(一)左移操作符——<<
(二)右移操作符 ——>>
四、位操作符
(一)按位与——&
(二)按位或——|
(三)按位异或——^
五、赋值操作符
(一)复合赋值符
六、单目操作符
(一)逻辑反操作符——!
(二)&(取地址)与*(解引用)
(三)sizeof关键字
(四)按位取反——~
(五)++/--
(六)(类型)——强转
(七)sizeof与数组
七、关系操作符
八、逻辑操作符
(一)&&
(二)||
九、条件操作符(三目操作符)
十、逗号表达式
+ - * / %
1、对于除法操作符来说,两边操作数是整数,执行的是整数除法。如果想计算小数,至少有一个操作数是浮点数。
2、除了取模操作符(%)外,其他操作符可用作于整数和浮点数。
3、取模操作符(%)两端操作数必须是整数,返回的是整除之后的余数。
int main()
{
int ret = 10 / 3;
double ret2 = 10.0 / 3;
printf("%d\n", ret);
printf("%lf\n", ret2);
return 0;
}
- << 左移操作符
- >> 右移操作符
注:移位操作符的操作数只能是整数。
数值12有多种表达形式——二进制:1100
八进制:14
十进制:12
十六进制:c
原码——按照一个数的正负,直接写出它的二进制表示形式得到的就是原码
反码——对于正数来说,与原码相同
对于负数来说,原码符号位不变,其他位按位取反
补码——对于正数来说,与原码相同
对于负数来说,反码+1
(负数)原码、补码相转化:
int main()
{
int a = 10;//一个整形占4字节=32bit
//10的二进制:1010
//0(符号位)0000000000000000000000000001010(原码)
//00000000000000000000000000001010(反码)
//00000000000000000000000000001010(补码)
int b = -10;//10000000000000000000000000001010(原码)
//11111111111111111111111111110101(反码)
//11111111111111111111111111110110(补码)
return 0;
}
1、正数移位
int main()
{
int a = 10;//00000000000000000000000000001010
int b = a << 1;//00000000000000000000000000010100(--20)
return 0;
}
2、负数移位
注:打印出来的都是原码(我们所看到的),计算机中存储的是补码
int main()
{
int a = -10;
int b = a << 1;
return 0;
}
1、分类:算术右移——右边丢弃,左边补原来的符号位(常用)
逻辑右移——右边丢弃,左边补0
int main()
{
int a = -1;
int b = a >> 1;
return 0;
}
- &——按位与
- |——按位或
- ^——按位异或
注:他们的操作数必须是整数。
int main()
{
int a = 3;
int b = -5;
int c = a & b;
printf("%d\n", c);//3
return 0;
}
int main()
{
int a = 3;
int b = -5;
int c = a | b;
printf("%d\n", c);//-5
return 0;
}
int main()
{
int a = 3;
int b = -5;
int c = a ^ b;
printf("%d\n", c);//-8
return 0;
}
补:a^a=0
0^a=a
支持交换律
=
- +=
- -=
- *=
- /=
- %=
- <<=
- >>=
- &=
- |=
- ^=
- !
- -
- +
- &
- sizeof
- ~
- --
- ++
- *
- (类型)
int main()
{
int flag = 0;
if (!flag)
printf("hehe\n");
return 0;
}
int main()
{
int flag = 0;
printf("%d\n", flag);//0
printf("%d\n", !flag);//1(不可随意取值)
return 0;
}
补充:unsnigned
int main()
{
unsigned int a = -10;
printf("%u\n", a);//4294967286(无符号位转换后直接输出)
return 0;
}
int main()
{
int a = 10;
printf("%p\n", &a);
int* pa = &a;
char* p = "abcdef";//常量字符串赋给p的是a的地址
printf("%p\n", p);//00007FF657029C14(a的地址)
printf("%c\n", *p);//a
return 0;
}
解引用操作
int main()
{
int a = 10;
int* pa = &a;
*pa = 20;//解引用
printf("%d\n", a);//20
return 0;
}
注:sizeof后面的(变量名),()可省略
sizeof内部表达式不参加计算
int main()
{
int a = 10;
short s = 5;
printf("%d\n", sizeof(a));//4
printf("%d\n", sizeof a);//4
printf("%d\n", sizeof(int));//此处()不可省 4
int arr[10] = { 0 };
printf("%d\n", sizeof(arr));//40
printf("%d\n", sizeof arr);//40
printf("%d\n", sizeof(int[10]));//40
printf("%d\n", sizeof(s=a+3));//2(计算s的大小——short对应2字节)
printf("%d\n", s);//5(sizeof内部表达式不参加计算)
return 0;
}
int main()
{
int a = 0;
printf("%d\n", ~a);
return 0;
}
int main()
{
int a = 10;
int b = a++;//先使用再自增(后置++)
printf("%d\n", a);//11
printf("%d\n", b);//10
return 0;
}
int main()
{
int a = 10;
int b = ++a;//先使用再自增(后置++)带有副作用——自身值也改变
printf("%d\n", a);//11
printf("%d\n", b);//11
return 0;
}
int main()
{
int a = (int)3.14;
printf("%d\n", a);//3
return 0;
}
void test1(int arr[])//数组传参,形参可以是数组名也可以是指针 ,本质——指针
{
printf("%d\n", sizeof(arr));//求指针变量大小——32位:4;64位:8
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch));
}
int main()
{
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("%d\n", sizeof(arr));//40 sizeof(数组名)——计算的是整个数组的大小
printf("%d\n", sizeof(ch));//10
test1(arr);//没放在sizeof内部也没有&,所以传过去的是数字名即首元素地址
test2(ch);
return 0;
}
>>=<<=!= 用于测试 “ 不相等 ”== 用于测试 “ 相等 ”
&& 逻辑与|| 逻辑或
exp1?exp2:exp3
T 算 不算
F 不算 算
int main()
{
int a = 10;
int b = 20;
int m = 0;
printf("%d\n",m = (a > b ? a : b));//20
return 0;
}
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d\n", c);//13
return 0;
}