12.操作符详解(位操作符、逗号表达式、下标访问操作符、函数调用操作符、操作数的优先级)

1.位操作符

1.1左移操作符(<<)

二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
将操作数的所有位向左移动指定的位数。左移 n 位相当于乘以 2 的 n 次方。

//左移操作符(<<)
int main() {
	int a = 5;//0000 0101 = 5
	int b = a << 1;//0000 1010 = 10
	printf("a << 1 = %d", b);
	return 0;
}

输出结果:
a << 1 = 10


1.2右移操作符(>>)

二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补 0,负数左补 1,右边丢弃。
将操作数的所有位向右移动指定的位数。右移n位相当于除以 2 的 n 次方。

//右移操作符(<<)
int main() {
	int a = 14;//0000 1110 = 14
	int b = a >> 1;//0000 0111 = 7
	printf("a >> 1 = %d", b);
	return 0;
}

输出结果:
a >> 1 = 7

注意:上述左移和右移操作符是位移运算符,不要移动负数位数,这是标准未定义的。


1.3按位与操作符(&)

对两个操作数二进制的每一位执行逻辑与操作,如果两个相应的位都为 1,则结果为 1,否则为 0。

//按位与(&)
int main() {
	int a = 5;//0000 0101 = 5
	int b = 3;//0000 0011 = 3
			  //0000 0001 = 1
	int result = a & b;
	printf("a & b = %d", result);
	return 0;
}

输出结果:
a & b = 1


1.4按位或操作符(|)

对两个操作数二进制的每一位执行逻辑或操作,如果两个相应的位都为 0,则结果为 0,否则为 1。

//按位或(|)
int main() {
	int a = 5;//0000 0101 = 5
	int b = 3;//0000 0011 = 3
			  //0000 0111 = 7
	int result = a | b;
	printf("a | b = %d", result);
	return 0;
}

输出结果:
a | b = 7


1.5异或操作符(^)

对两个操作数二进制的每一位执行逻辑异或操作,如果两个相应的位值相同,则结果为 0,否则为 1。

//按位异或(^)
int main() {
	int a = 5;//0000 0101 = 5
	int b = 3;//0000 0011 = 3
			  //0000 0110 = 6
	int result = a ^ b;
	printf("a ^ b = %d", result);
	return 0;
}

输出结果:
a ^ b = 6

注:&、|、^三种位操作符的操作数必须是整数。


1.6取反操作符(~)

对操作数的每一位执行逻辑取反操作,即将每一位的 0 变为 1,1 变为 0。
取反的具体过程:
1.先将操作数化为补码
2.再对补码进行取反(0 变为 1,1 变为 0)
2.将取反后的补码再转变为原码,得出的值就是原操作数取反后的值。

//取反(~)
int main() {
	int a = 5;
	//a原码:0000 0101 = 5
	//a补码:0000 0101
	int result = ~a;
	//a取反:1111 1010
	//然后再将取反后的补码转换为原码
	//反码:1111 1001
	//原码:1000 0110 = -6
	printf("~a = %d", result);
	return 0;
}

输出结果:
~a = -6

注:&、|、^三种位操作符的操作数必须是整数。


练习

1.在不创建临时变量(第三个变量)的情况下,实现两个数的交换

int main() {
	int a = 5;
	int b = 3;
	printf("交换前 a=%d b=%d\n", a, b);

	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("交换后 a=%d b=%d", a, b);
	return 0;
}

在这里插入图片描述

用个人的话来发现其中的规律,就是两个整数(假设A和B)异或后得到的数(假设为C)
用C去异或A或B其中一个数,所得的数为没有参加异或的那个数。
例如
∵A ^ B = C
∴C ^ A =B或者C ^ B =A
借助这一特性不需要创建临时变量也可以实现两个数的交换。

2.逗号表达式

逗号表达式就是用逗号隔开的多个表达式。
逗号表达式,从左至右一次执行。整个表达式的结果是最后一个表达式的结果。

//代码一
int main() {
	int a = 1,b = 2;
	int c = (a = b -a, a = b + 10, a, b = a + 1);//所以c应该是最后一项b = a + 1的值
	printf("%d", c);
	return 0;
}

输出结果:
13

//代码二
int main() {
	int a = 1, b = 2, c = 3;
	if (a = b + 1, c = a / 2, c > 0) {
		printf("c=%d", c);
	}
	return 0;
}
/*
(a = 3,c=1,1>0) 1>0成立等于1,所以执行if语句
*/

输出结果
c=1


3.下标访问[]、函数调用()

3.1下标引用操作符 [ ]

//数组下标[
int main() {
	int arr[5] = { 1, 2, 3, 4, 5 };
	//	   0  1  2  3  4

	printf("%d", arr[4]);//5
	return 0;
}

arr[4]
下标操作符[]的操作数是:数组名arr 和 4(下标索引位)

3.2函数调用操作符 ()

//函数的定义
int add(int x,int y) {
	int z = x + y;
	return z;
}

//函数调用()
int main() {
	printf("%d", add(1, 2));//3
	return 0;
}

add(1,2)
函数操作符()的操作数是:函数名add,1,2

问题一:
()函数调用操作符最少有几个操作符?
1个,也就是只写个函数名,即无参函数。


问题二:
sizeof()是不是函数呢?
sizeof不是函数,记住不是函数!sizeof是操作符!!!
上代码!

//sizeof是操作符
int main(){
	int a = 10;
	//int n = sizeof(a);
	int n = sizeof a;
	printf("%d\n", n);
	return 0;
}

结果发现sizeof(a)的效果和sizeof a相同,所以证明sizeof不需要函数调用操作符()也能正常运行,而调用函数必须要有()才可以调用。

4.操作数的优先级

在这里插入图片描述

优先级和结合性决定了表达式求值的计算顺序
如果优先级相同,这时看结合性。大部分运算符都是(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符(=)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值