C语言—知识点—操作符1

1.左移操作符

正整数的原码反码补码相同都等于原码, 负整数的原码、反码、补码是要计算的,计算方法如下:

  •  原码:把数字直接用二进制表示就是原码
  •  反码:原码的符号位不变,其他位按位取反就是反码
  •  补码:反码加一就是补码

并且,在内存中存储的是二进制的补码。所以移位操作符是移动的是一个二进制位,且是补码。

具体做法是左边丢弃右边补0。左移有乘2的效果。

2.右移操作符

右移操作符分为两种:

1.算术移位:右边丢弃,左边补原符号位

2.逻辑移位:右边丢弃,左边补0

要判断是算术移位还是逻辑移位用一个负数。

注意:1.左移操作符和右移操作符都只针对整数,浮点数不适用

           2.对于移位运算符,不要移动负数位,这个是标准未定义的

3.位操作符

  •  & —按(2进制)位与
  •  | — 按(2进制)位或
  •  ^ —按(2进制)位异或

        都是对补码进行位操作

        &是只有两位同为1结果才为1,不然结果都为0

        | 是只要有1结果就为1,只有两位都为0结果才是0

       ^ 是相同为0,相异为1

int main()
{
	int a = 3;
	int b = -5;
	int c = a & b;

	//000000000000000000000011  - 3的补码
	//100000000000000000000101
	//111111111111111111111010
	//111111111111111111111011  -5的补码

	//000000000000000000000011  -按位与的结果(也是补码)
	//111111111111111111111011  -按位或的结果(补码)
	//111111111111111111111000  -按位异或的结果(补码)
	//

	return 0;

}

示例:

问题:不创建临时变量交换两个数 

(解法一)

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

	a = a + b;
	b = a - b;
	a = a - b;
	printf("交换后: a=%d b=%d\n", a, b);

	return 0;

}

注意:在a和b都在范围内时,a+b的和也可能会溢出。 

(解法二)

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

	a = a ^ b;
	b = a ^ b;
	a = a ^ b;

	printf("交换后:a=%d b=%d\n", a, b);

	return 0;

}

注意:两个相同的整数异或的结果为0,一个整数和0异或的结果为这个数本身。并且异或操作符支持交换律及结合律。所以   3^5^3的结果是5 。

 补充:~是按位取反

sizeof

sizeof() 是一个判断数据类型或者表达式长度的运算符

注意:sizeof是一个单目操作符 ,而不是函数。而strlen是库函数,不是操作符。

int main()
{

	int a = 0;
	printf("%d\n", sizeof(a));//正确
	printf("%d\n", sizeof(int));//正确
	printf("%d\n", sizeof a);//正确
	printf("%d\n", sizeof int );//错误

    return 0;
}

前三种写法正确,最后一种写法错误。 

示例

void test1(int arr[])
{
	printf("%d\n", sizeof(arr));
}

void test2(char ch[])
{
	printf("%d\n", sizeof(ch));
}

int main()
{
	int arr[10] = { 0 };
	char ch[10] = { 0 };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(ch));
	test1(arr);
	test2(ch);
	return 0;
}

输出结果为: 40 10 4 4.

对函数 test1和test2来说,计算的都是一个指针的大小,因此都是四个字节。 

&&和 | |

逻辑操作符只关注真假。

&&相当于并且,只有左右两边均为真结果才为真。

| | 相当于或者,左右两边有一个为真则为真。 

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;
}

输出结果: 1 2 3 4

因为使用&&,只要有一方是0,则结果为假。又因为a为后置++,所以先使用。因此&&的左边是假,无论右边是什么,结果都为假,因此&&右边的式子不会计算了。  同理, ||左边为真,右边就不计算了。

条件操作符(三目操作符)

 exp?exp2:exp3

exp是否为真?为真则计算表达式2的结果,并且表达式2的结果为整个表达式的结果。如果为假则计算表达式3的结果,并且表达式3的结果为整个表达式的结果。

补充:结构体指针->成员等价于 结构体对象.成员

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值