目录
位操作符例题:不使用中间变量,交换两个数的值(创建中间变量的方法最高效,最常用)
一、算术操作符 + - * / %
1、/ 除法
整数除法:定义整型变量,除号左右两端都是整型
int a = 7 / 2;
printf("%d\n", a);//计算结果为3
浮点数除法:定义浮点型变量,除号两端只要一个有一个小数就执行浮点数除法
float c = 7 / 2.0;
printf("%f\n", c);//计算结果为3.500000
特别注意:
float b = 7 / 2;
printf("%f\n", b); //计算结果为3.00000(1)不在于存储到什么类型中,在于本身计算结果:7/2结果为3,将整型3存储到浮点类型中,转换为3.0
(2)除数不能为0
2、 %取模(取余数)
(1)取模,即取整除后的余数;
(2)取模操作符必须为两个整数 ;
int e = 7 % 2;
printf("%d\n", e);//结果为1: 2*3得6,余1
(3)取模操作符的应用:剥离整数的每一位:例123,剥离每一位,1,2,3
void print(int n)
{
if (n > 9)
{
print(n / 10);
}
printf("%d ", n%10);
}
(4)取模操作符的应用:随机生成一个0~n之间的整数,n指定
int n = 0;
srand((unsigned)time(NULL));
n = rand();//n,生成的随机数
printf("%d\n", n % 30);//随机数模30,取余值的范围必为0~30(满30则进1)
二、移位操作符
移位操作符的操作数只能是整数,移动的是二进制补码;左移*2,右移/2(向下取整);算术右移是右边直接丢弃,左边补原来的符号位;逻辑右移是右边直接丢弃,左边补0;左移是左边直接丢弃,右边补0;一般编译器采用算术右移,C语言未明确规定; 可用负整数移位结果来判断是算术移位还是逻辑移位;对于移位操作符,不要移动负数位,这是标准未定义行为;
整数的二进制表示形式有3种:原码、反码、补码
1、整数在内存中存储的是补码,计算式时也使用补码;
2、正整数:首位符号位为0,原码 反码 补码相同;
3、负整数:首位符号位为1,原码变反码,符号位不变,其他位按位取反;反码加一变补码;
int n = 15;
int b = n >> 1; //右移一位
printf("%d\n", b); //7
int c = n << 1; //左移
printf("%d\n", c); //30
int a<<=1; //复合赋值,左移1位
三、位操作符 :只适用于整数
1、按(二进制)位与 &
两个整数进行位操作,若对应补码二进制位都是1,则位操作后的二进制序列对应位是1;若含有0,则为0(有0则0,都为1才1)
int a = 3;
//00000000000000000000000000000011 : 3的补码
int b = -5;
//10000000000000000000000000000101 : -5的原码
//11111111111111111111111111111010 : -5的反码,符号位不变
//11111111111111111111111111111011 : -5的补码,符号位不变
int c = a & b;
//00000000000000000000000000000011 : 3的补码
//11111111111111111111111111111011 : -5的补码
//00000000000000000000000000000011 : 按位与操作结果:3
2、按(二进制)位或 |
两个整数进行按位或操作,若对应的二进制为有1,则位操作后的二进制序列对应位是1;若同时为0,则为0(有1则1,没1则0)
int a = 3;
int b = -5;
int d = a | b;
//00000000000000000000000000000011 : 3的补码
//11111111111111111111111111111011 : -5的补码
//11111111111111111111111111111011 : 按位或操作结果:补码
printf("%d\n",d);
//%d答应有符号的整数,即存储在计算机中的原码
//11111111111111111111111111111010 : 按位或操作结果:反码
//10000000000000000000000000000101 : 按位或操作结果:原码:-5
3、按(二进制)位异或
相同为0,相异为1
(1)两个相同的数字异或,完全相同为0(3^3=0)
(2)0异或任何数,都等于这个数本身(0^3=3)
(3)异或操作符支持交换律(2^3^2=2^2^3=0^3=3)
int a = 3;
int b = -5;
int e = a ^ b;
//00000000000000000000000000000011 : 3的补码
//11111111111111111111111111111011 : -5的补码
//11111111111111111111111111111000 : 按位异或操作结果:补码
printf("%d\n",e);
//%d答应有符号的整数,即存储在计算机中的原码
//11111111111111111111111111110111 : 按位或操作结果:反码
//10000000000000000000000000001000 : 按位或操作结果:原码:-8
位操作符例题:不使用中间变量,交换两个数的值(创建中间变量的方法最高效,最常用)
a = a ^ b;//方法一:弊端,位操作符 只适用于整数
b = a ^ b;
a = a ^ b;
a = a + b;//方法二:弊端,a、b同时为最大值 相加的结果会溢出
b = a - b;
a = a - b;
位操作符例题:查找一个整数存储在内存中的二进制位中有几个1
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
printf("%d\n", count);
位操作符例题:求两个整数二进制表达中不同(bit)位的个数
int m = 1999, n = 2299;
int count = 0;
for (int i = 0; i < 32; i++)
{
if (((m>>i)&1)^(n>>i)&1)
{
count++;
}
}
printf("%d\n", count);//7
四、赋值操作符
1、赋值操作符
在变量创建好之后,为变量赋值,可连续赋值(注意:在创建变量的同时为变量赋初值,称初始化)
int a = 3;//初始化
int b = 0;
b = 10;//赋值
2、符合赋值符
a = a + 3;
a += 3;//复合赋值符
a = a << 2;
a <<= 2;
五、单目操作符(只有一个操作数 )
举例:!逻辑反操作 +正值 -负值 &取地址操作符 sizeof
1、!逻辑反操作
if (a)//只有a为真值,才能进入if
{
printf("%d为真 ",a);
}
else if (!a)//只有a为假,!a才为真,才能进入if
{
printf("%d为假 ",a);
}
int b = 0;
if (b)
{
printf("%d为真 ",b);
}
else if (!b)
{
printf("%d为假 ",b);
}
此段代码结果为:3为真 0为假
2、取地址操作符
打印变量在内存中的起始地址
int a = 9;
printf("%p\n", &a);//&取地址操作符,%p打印地址
3、sizeof操作符
计算类型创建的变量所占内存空间的大小,单位字节 ;
int a = 3;
printf("%d\n", sizeof(a));//变量a所占内存空间的大小4
printf("%d\n", sizeof(int));//变量的类型为int,计算类型创建的变量所占内存空间的大小4
int arr[6] = { 0 };
printf("%d\n", sizeof(arr));//6*4=24数组中包含6个int类型的整数