C语言-运算符

新知

  • 如果左移n位,就相当于在原来的基础上乘以 2的n次方
  • %d 输出 0xffff ffff ,输出为-1.
    %u 输出 0xffff ffff ,输出为4294967295.
  • 右移的补位
    如果x是signed ,那么高位全部补符号位
    如果x是unsigned,那么高位全部补0
char c = -56 >> 30;//右移30位后得:0xffff ffff。强制转换位char,c = 0xff;  
printf("%d\n",c);//%d表示有符号整型输出,0xffff ffff 是-1的补码,所以输出-1
printf("%u\n",c);//%u表示无符号整型输出,0xffff ffff = 4294967295

//-56u 表示把 -56整型数 转换为 无符号整型数
char c = -56u >> 30;//-56 在计算机存储的格式是补码: 0xffffffc8;右移30位,无符号右移高位补0,然后强制转换位char型:0x03
printf("%d\n",c);//0x03 = 3 
printf("%u\n",c);//0x03 = 3
  • 异或
    与1异或即取反
    与0异或就是本身

    利用 异或的交换律 实现无中间变量 互换变量值
  • 逗号运算符
    最后的表达式才是结果
  • 作业题目!!!
    将x(int)中第m位开始的连续n个bit位取反,其余各位保持不变

0. sizeof()是运算符,也是关键字

1. C语言取整数

取整风格共有3种:
向零取整。即向坐标轴0的方向,取最近的整数。
向上取整。也就是向+∞取整,即取不小于结果的最小整数。
向下取整。也就是向-∞取整,即取不大于结果的最大整数。

所以,C语言中计算-5除以3,因为实数结果约为-1.67,向零取整,得到结果为-1。

2. 负数取余

#include <iostream>
using namespace std;

int main()
{
    cout<<(5%3)<<endl;		//5=3x1+2
    cout<<(-5%-3)<<endl;	//-5=-3x1-2
    cout<<(5%-3)<<endl;		//5=-3x(-1)+2
    cout<<(-5%3)<<endl;		//-5=3x(-1)-2
    system("pause");
    return 0;
}

在这里插入图片描述

3. 异或的妙用

与1异或即取反
与0异或就是本身

	^		按位异或
		求异,不同为1,相同为0
		a和b都是1bit
		a		b		a^b
		0		0		0
		0		1		1
		1		0		1
		1		1		0		
				
		通过上面可以得出结论:
		1,一个bit位与1进行 ^ 运算,结果是 取反
				a ^ 1  -> ~a
		2,一个bit位与0进行 ^ 运算,结果是 它本身
				a ^ 0  -> a
				

利用 异或的交换律 实现无中间变量 互换变量值

	
			练习:
				有两个整型变量 a,b;
				a ^ b ^ a 	-> b
				
				^满足“交换律”,那么a ^ b ^ a  等价 a^a^b
				a ^ a -> 0
				0 ^ b -> b
				---------------------------------------------
				交换两个int型数据 a,b的值,不能使用其他变量
									a				b
				a = a + b;			a+b				b
				b = a - b;			a+b				a+b-b=a
				a = a - b;			a+b-a=b			a
				----------------------------------------------
				a = a^b;			a^b				b
				b = a^b;			a^b				a^b^b = a
				a = a^b;			a^b^a=b			a

4. 左移/右移

		例子:
			123 << 4   -> 1968
			
			000..0000 0111 1011 << 4
			1*2^0 + 1*2^1 + 1*2^3 + 1*2^4 + 1*2^5 + 1*2^6 
			
			00..000111 10110000   -> 1968
			1*2^4 + 1*2^5 + 1*2^7 + 1*2^8 + 1*2^9 + 1*2^10
			->
			2^4*(2^0+1*2^1 + 1*2^3 + 1*2^4 + 1*2^5 + 1*2^6 )
			
		结论:如果左移n位,就相当于在原来的基础上乘以 2的n次方。前提是高位丢弃的全是0
按位右移
		x >> n 把x按bit位整体往右移动n bit位
			低位右移后,直接丢弃
			高位补什么?
				如果x是signed ,那么高位全部补符号位
				如果x是unsigned,那么高位全部补0
			
			123 >> 3 
			
			000..0000 0111 1011  >> 3 
			000000..0000 0111 1 ->15
			
		练习:
			1,假设一个int型变量 a,要把a的bit n变为1,其他Bit保持不变
					a =  (1<<n) | a

			2,假设一个int型变量 a,要把a的bit n变为0,其他Bit保持不变						
					   111111101111111
					  ~000000010000000	
						 a = ~(1<<n) & a

负数右移

原码,反码,补码理解

	printf("%d\r\n", -6>>2);//-2
	printf("%d\r\n", -9 >> 2);//-3

-6>>2
在32位系统中,首先-6的二进制形式是1000 0000 0000 0110

  1. 反码是1111 1111 1111 1001
  2. 补码是反码+1:1111 1111 1111 1010,其十六进制是fffa,由下图可知负数在计算机中是以补码的形式保存的。
  3. -6右移2位,得到1111 1111 1111 1110.(注意:有符号数右移补符号位,系统默认整数常量为signed int 型,故这里右移补符号位1)
  4. 右移的结果取反+1转化为原码:1000 0000 0000 0010= -2.

在这里插入图片描述

5. 逗号运算符

,
	双目运算符,优先级最低,结合性从左到右
		语法: 表达式1,表达式2,表达式3,,,,,,,,,表达式n
		
		逗号表达式的运算顺序是:先求表达式1的值,再求表达式2的值,......最后求表达式3的值
		整个逗号表达式的值为最右边的那个表达式的值。
		
		
		例子:
			3+6,7*9,5/2   ->这个逗号表达式的值为2
			
		int main()
		{
		    int a;
		    a = 3 + 6, 7 * 9, 5 / 2;//逗号表达式,逗号运算符优先级最低,一开始就先赋值了
		    printf("a=%d\n", a);//9
		
		    a = (3 + 6, 7 * 9, 5 / 2);//用括号括起来,先做逗号运算得到5/2=2,再做赋值运算 a = 2
		    printf("a=%d\n", a);//2
		}

6. 逻辑运算符有短路特性

&&、||运算符短路特性

    int a = 1, b = 2, c = 3, d = 4;
    int m = 1, n = 1;
    
    (m = a > b) &&(n = c > d);//逻辑运算&&左边为假,右边的不用运算了
    printf("m = %d\tn = %d\n", m, n);//m = 0 n = 1

    (m = a > b) ||(n = c > d);//逻辑运算||左右两边都有运算
    printf("m = %d\tn = %d\n", m, n);//m = 0 n = 0

7. 赋值运算符的拓展是自右向左

int main()
{
    int a = 1;

    a += a *= a += 3;//自右向左,a = a+3 = 4; a = a*4 = 16; a = a + 16 = 32;

    printf("a:%d\n", a);//a:32
}

8. 位运算(与底层打交道)

>> 、<<、 ~、 | 、&、 ^ 、
~表示按位取反,注意不要用成!

num |= 1<<n;//将操作数中第n位置1,其他位不变
num &= ~(1<<n);//将操作数中第n位清0,其他位不变
  • 将操作数中的第n位置1,其他位不变:
    num = num |1<<n;
  • 将操作数中的第n位置0,其他位不变:
    num = num &~(1<<n);
  • 测试第n位:
    if(num & 1<<n)
  • 将x(int)中第m位开始的连续n个bit位取反,其余各位保持不变
    x = (((1<<n)-1)<<m) ^ x;
  • 将x中的第m位开始的n个bit位设置为y中的最右边的n个bit的值,x的其余各位保持不变

作业

常出错:
%d 输出 ffff ffff ,输出为-1.
%u 输出 ffff ffff ,输出为4294967295.

作业
1.x(int)中第m位开始的连续n个bit位取反,其余各位保持不变

int main()
{
    int x = 255;
    int m = 1;//第1为开始
    int n = 4;//连续4位
    int i;
    printf("%x\r\n", x);

   
    x = (((1<<n)-1)<<m) ^ x;
    printf("%x\r\n", x);

}

2,将x中的第m位开始的n个bit位设置为y中的最右边的n个bit的值,x的其余各位保持不变

 int main()
{
    int x = 255;//1111 1111
    int y = 30;//0001 1110
    int m = 1;//第1为开始
    int n = 4;//连续4位
    
    
    x = x & (~(((1 << n) - 1) << m));//把x中对应的位清0
    printf("%x\r\n", x);
    y = y & ((1 << n) - 1);//取y中的m bit
    x = x | (y << m);//把y填入x中
    printf("%x\r\n", x);

    ((y & ((1 << n) - 1)) << m) | (~(((1 << n) - 1) << m) & x);

}
	3.分析如下程序的输出结果
		char c = -56 >> 30;
			负数的补码:绝对值的原码取反加一
			0000..000000111000
			1111..111111000111
			1111..111111001000 >> 30 
		
			111..1111...1111
			
			11111111
			
		printf("%d\n",c);
		printf("%u\n",c);
		----------------------
		char c = -56u >> 30;
		printf("%d\n",c);
		printf("%u\n",c); 
		
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值