C语言操作符经典例题

一、选择题

1、下面哪个是位操作符:( )

A.&

B.&&

C.||

D.!

答案解析:

答案:A

A正确,&——按(二进制)位与,对应的二进制位:有0则0,两个同时为1才为1。

B、C错误,&&与||——逻辑操作符

D错误,!——单目操作符

知识点:

1、位操作符:

        (1)运算规则:

                ①&——按(2进制)位与,对应的二进制位:有0则0,两个同时为1才为1

                ②|——按(2进制)位或,对应的二进制位:有1则1,两个同时为0才为0

                ③^——按(2进制)位异或,对应的二进制位:相同为0,相异为1

        (2)注意:

                ①他们的操作数必须是整数

                ②是针对二进制位进行运算的

2、逻辑操作符

        (1)运算规则

                ①&&——逻辑与(并且:参与运算的两个逻辑值都为真时,结果为真)

                ②||——逻辑或(或者:参与运算的两个逻辑值都为假时,结果为假)

        (2)逻辑操作符的短路特性

                ①&&操作符,左边为假,右边无需计算

                ②||操作符,左边为真,右边无需计算

        (3)注意区分逻辑与(或)和按位与(或)

                ①逻辑与(或)----->只关注真假

                ②按位与(或)----->通过二进制计算得到

二、编程题

1、交换两个变量(不创建临时变量)

不允许创建临时变量,交换两个整数的内容

方法1:计算得到

方法2:使用按位异或操作符

 知识点:

1、按位异或操作符

        (1)运算规则:^——按(二进制)位异或,对应的二进制位:相同为0,相异为1

        (2)性质:

                ①a^a=0

                ②0^a=a

                ③异或支持交换律:a^a^b=a^b^a

         (3)异或操作符交换两个变量的局限性

                ①可读性差

                ②效率也不如使用临时变量的方法

                ③异或只针对整数的交换

代码1:计算得到

#include<stdio.h>

int main()
{
	int a = 0;
	int b = 0;
	//输入a,b
	scanf("%d %d", &a, &b);
	//打印交换前a,b
	printf("交换前:a=%d b=%d\n", a, b);
	//交换a,b
	a = a + b;
	b = a - b;
	a = a - b;
	//打印交换后a,b
	printf("交换后:a=%d b=%d\n", a, b);

	return 0;
}

代码2:使用按位异或

#include<stdio.h>

int main()
{
	int a = 0;
	int b = 0;
	//输入a,b
	scanf("%d %d", &a, &b);
	//输出交换前a,b
	printf("交换前:a=%d b=%d\n", a, b);
	//交换a,b
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	//输出交换后a,b
	printf("交换后:a=%d b=%d\n", a, b);

	return 0;
}

2、统计二进制中1的个数

二进制中1的个数__牛客网

1、在网上平台答编程题(如牛客网),有两类:

        ①IO型:从main函数开始写,要写输入、计算、输出等

        ②接口型:不需要写主函数,默认主函数就是存在的(后台存在),你只需要完成函数就可以了。

本题就是一道接口型。

我们平时练习可以在自己的编译器,先实现再复制粘贴到答题平台上验证。

代码1:

我们是怎么得到10进制整数的每一位的?

类比:

  这种方法虽然也能求出2进制中1的个数,但是我们把题目给的形参改变了,所以不符合题意。排除掉。

#include<stdio.h>

int NumberOf1(unsigned int n) 
{
	int count = 0;//计数器,统计1的个数
	//循环%2 /2,直到n等于0
	while (n)
	{
		if (n % 2 == 1)
		{
			count++;
		}//如果是1,统计
		n /= 2;//循环调整部分
	}
	return count;
}

int main()
{
	int n = 0;
	//输入
	scanf("%d", &n);
	//计算--调用函数
	int ret = NumberOf1(n);
	//输出
	printf("%d\n", ret);

	return 0;
}

代码2:

我们写的这个代码没有修改题目函数的返回类型、函数名、形参所以粘贴复制到牛客网是成功的。

知识点:

1、>>右移操作符

        移位规则:

                ①(常见如VS)算术右移:左边补原来的符号位,右边抛弃

                ②逻辑右移:左边直接补0,右边抛弃

2、&——按位与

        移位规则:对应的二进制位:有0则0,两个同时为1才为1

3、总结:我们判断一个数的每一位的数时,通常从低位入手 

4、n虽然发生了右移,但是实际上n在没有被赋值的情况下,自身的值不会发生变化(即n>>i的结果是移位之后的效果,但是n是不变的)

#include<stdio.h>

int NumberOf1(int n)
{
	int count = 0;//计数器,统计1的个数
	int i = 0;//循环变量
	//循环32次,每次右移i
	for (i = 0; i < 32; i++)
	{
		if ((n >> i) & 1)
		{
			count++;
		}
	}
	return count;
}

int main()
{
	int n = 0;
	//输入
	scanf("%d", &n);
	//计算--调用函数
	int ret = NumberOf1(n);
	//输出
	printf("%d\n", ret);

	return 0;
}

代码3:

但是还有效率更高的解法:

我们粘贴函数部分上牛客验证:

  

#include<stdio.h>

int NumberOf1(int n)
{
	int count = 0;//计数器,统计1的个数
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	return count;
}

int main()
{
	int n = 0;
	//输入
	scanf("%d", &n);
	//计算--调用函数
	int ret = NumberOf1(n);
	//输出
	printf("%d\n", ret);

	return 0;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值