目录
算数操作符
%操作符的两个操作数必须是整数
位移操作符
>> 将值在内存中存储的二进制位向右移动 位
<< 将值在内存中存储的二进制位向左移动 位
//原码的符号位(第一位)不变,其他位按位取反得到的就是反码
//反码的二进制+1,得到的就是补码
int a=5;
//正数
a是整型,a占个字节->32bit
00000000000000000000000000000101 - 原码
00000000000000000000000000000101 - 反码
00000000000000000000000000000101 - 补码
.
int a=-5;
//负数
10000000000000000000000000000101 - 原码
111111111111111111111111111111111010 - 反码
111111111111111111111111111111111011 - 补码
左移操作符:
#include<stdio.h>
int main()
{
int a = -5;
//把a在内存中存储的二进制位向左移动2位
int b = a << 2;
printf("%d\n", b);
printf("%d\n", a);
return 0;
}
如图,因为计算机以补码的方式储存
(打印或使用时,用原码值)
11 11111111111111111111111111101100 补码左移2位
111111111111111111111111111101011 补码-1变反码
10000000000000000000000010100 除符号位不变其他按位取反 变原码
最后以原码输出-----b=-20,a=-5
右移操作符:
1.算术右移(右边丢弃,左边补原来的符号位)
2. 逻辑右移(右边丢弃,左边补0)
到底右移是算术还是逻辑右移,取决于编译器
我们常见的编译器下都是算术右移
#include<stdio.h>
int main()
{
int a = -5;
int b = a >> 1;
printf("%d\n", b);
return 0;
}
如图,-5
10000000000000000000000000000101 - 原码
111111111111111111111111111111111010 - 反码
111111111111111111111111111111111011 - 补码
1111111111111111111111111111111111011 - 补码右移一位,左边补原来的值
111111111111111111111111111111111100 - 减一变反码
10000000000000000000000000000011 - 原码
最后以原码输出-----b=-3
(对于移位运算符不可移负数,此为标准未定义行为)
位操作符
& - 按(2进制)位与---------------全1则1,否则为0
| - 按(2进制)位或---------------有1则1,全0为0
^ - 按(2进制)位异或-------------相同为0,相异为1
int main()
{
int a = 3;
int b = -5;
//int c = a & b;
//int c = a | b;
int c = a ^ b;
printf("%d\n", c);
return 0;
}
单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
1. !: !假=真(1) !真=假(0)
2. sizeof:(\0也算)
int main()
{
int a = 10;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(int));--->4
int arr[10] = { 1,2,3,4,5,6 };
printf("%d\n", sizeof(arr));//40字节
printf("%d\n", sizeof(int[10]));//40
int a = 10;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof a);
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(int));--->4
}
3. ~ : 对一个数的二进制按位取反
int main()
{
int a = 0;
//~ 按(内存中补码的2进制)位取反
//00000000000000000000000000000000
//11111111111111111111111111111111 - 补码
//11111111111111111111111111111110 - 反码
//10000000000000000000000000000001 - 原码 --> -1
printf("%d\n", ~a);
return 0;
}
int main()
{
int a = 10;
a |= (1 << 2);
printf("%d\n", a);
a &= ~(1 << 2);
printf("%d\n", a);
//00000000000000000000000000001010
//00000000000000000000000000000100 1<<2
//00000000000000000000000000001110
//11111111111111111111111111111011 ~(1<<2)
//00000000000000000000000000001010
return 0;
}
小知识:EOF -------> -1 所有~EOF==0 即
while(scanf("%d",&n)!=EOF)
while(~scanf("%d",&n)) //两段代码意义相同
4.(类型) 强制类型转换
int main()
{
int a = (int)3.14;//3.14 - double -> int a
printf("%d\n", a);---->3
return 0;
}
逻辑操作符
(int b = ++a;//前置++,先++,后使用 int b = a++;//后置++,先使用,再++)
&&:只要逻辑与判定值为假(即为0),后面的语句都不执行
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
return 0;
}
//输出 1234
||:只要逻辑或判定值为真(即为非0),后面的语句都不执行
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++||++b||d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
return 0;
}
//输出 1334
注:从左到右依次判断(算出左值后代值与右计算)
条件操作符
三目操作符: x?a:b x真则执行a,否则b
int main()
{
int a = 10;
int b = 20;
int max = 0;
if (a > b)
max = a;
else
max = b;
//条件操作符
max = (a > b ? a : b);
b = (a > 5 ? 3 : -3);
return 0;
}
逗号表达式
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
int main()
{
int a = 3;
int b = 5;
int c = 6;
int d = (a+=2, b=a-c, c=a+2*b);
printf("%d\n", d); ------>3
return 0;
}
结构体成员
.
->
#include<stdio.h>
struct Stu
{
char name[20];
int age;
double score;
};
int main()
{
struct Stu s = {"zhangsan", 20, 85.5};
//.
printf("%s %d %.1lf\n", s.name, s.age, s.score);//结构体变量.结构体成员
//->
struct Stu * ps = &s;
//printf("%s %d %.1lf\n", (*ps).name, (*ps).age, (*ps).score);
printf("%s %d %.1lf\n", ps->name, ps->age, ps->score);//结构体指针->结构体成员
return 0;
}