【C语言】位操作符与移位操作符练习

简介: 【C语言】位操作符与移位操作符练习

前言:

前篇我们学习过C语言的位与移位操作符详解【C语言】位与移位操作符详解-CSDN博客

这篇博客将带领大家继续练习相关知识。

1.一道变态的面试题

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

解析:通过上节我们学习的位与移位操作符,我们可以大概知道需要用到它们。

通过学习我们可知:

①a & a = a ②a | a = a ③a ^ a = 0 ④a & 0 = 0 ⑤a | 0 = a ⑥a ^ 0 = a①a & a = a ②a | a = a ③a ^ a = 0 ④a & 0 = 0 ⑤a | 0 = a ⑥a ^ 0 = a

要交换两个整数的内容我们要使用③⑥两个公式

a^a^b=b

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
//不允许创建临时变量,交换两个整数的内容
#include<stdio.h>
int main()
{
  int a = 3;
  int b = 5;
  a = a ^ b;
  b = a ^ b;//实际上是a^b^b=a^0=a
  a = a ^ b;//实际上是a^b^a=0^b=b
  
  printf("%d\n", a);
  printf("%d\n", b);
 
  return 0;
}

运行结果如下:

2.输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。

方法一:

解析:我们知道按位与是同真为真也就是二进制中都是1才为1,只要有一个不为1就是0;

所以如果我们将n按位与1(1的二进制除了最后一位其他都是0),那么我们就可以知道n最后一位是1还是0了,如果再通过右移操作符将n的二进制一回移动一个,那么我们就可以得知n每位是1还是0了,问题就得到解决啦~

🎉🎉✨检测num中某一位是0还是1的方式:

1.将num向右移动i位

2.将移完位之后的结果与1按位与,如果.结果是0,则第i个比特位是0,结果是非0,则第i个比特位是1

以下是解析图:

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
 
//2.输入一个整数 n ,输出该数32位二进制表示中1的个数。
// 其中负数用补码表示。
int main()
{
  int n = 0;
  printf("请输入整数n:");
  scanf("%d", &n);
  int i = 0;//创建i变量用以循环32次
  int count = 0;//创建count变量用以记录i的个数
  for (i = 0; i < 32; i++)
  {
    count += (n>>i) & 1;
  }
  printf("\n%d的二进制中1的个数为:%d\n",n,count);
  return 0;
}

运行结果如下:

方法一

优点:用位操作代替取模和除法运算,效率稍微比较高

缺陷:不论是什么数据,循环都要执行32次

方法二:

代码如下:

int main()
{
  int n = 0;
  printf("请输入整数n:");
  scanf("%d", &n);
  int count = 0;//创建变量计数
  while (n & (n - 1))//当n与相邻位按位与不为0时
  {
    n = n & (n - 1);
    count++;
  }
  count += 1;//注意最后为0的也要算进去
  printf("\n二进制中1的个数为:%d\n",  count);
  return 0;
}

这里要注意两点💥:

(1)n&(n-1)后要将它的值赋给n,而不是将n-1赋给n;

n = n & (n - 1);

(2)最后n&(n-1) = 0时while已经出了循环,所以最后count还要+1

count += 1;//注意最后为0的也要算进去

代码运行结果如下:

方法三:

代码如下:

int main()
{
  int n = 0;
  printf("请输入整数n:");
  scanf("%d", &n);
  int count = 0;//创建变量计数
  while (n)
  {
    if (n % 2 == 1)
      count++;
    n =n/ 2;
  }
  printf("\n二进制中1的个数为:%d\n", count);
}

运行结果如下:

上述方法缺陷:进行了大量的取模以及除法运算,取模和除法运算的效率本来就比较低。

3.打印整数二进制的奇数位和偶数位

思路:

1.提取所有的奇数位,如果该位是1,输出1,是0则输出0

2.以同样的方式提取偶数位置(我们可以用移位操作符来提取)

💫检测num中某一位是0还是1的方式:

1.将num向右移动i位

2.将移完位之后的结果与1按位与,如果.结果是0,则第i个比特位是0,结果是非0,则第i个比特位是1

代码如下:

int main()
{
  int num = 0;
  printf("请输入整数num:");
  scanf("%d", &num);
  for (int i = 31; i >= 1; i -= 2)
  {
    printf("%d ", (num >> i) & 1);
  }
  printf("\n");
 
  for (int i = 30; i >= 0; i -= 2)
  {
    printf("%d ", (num >> i) & 1);
  }
  printf("\n");
  return 0;
}

运行结果如下:


相关文章
|
3月前
|
存储 C语言 索引
【C语言篇】操作符详解(下篇)
如果某个操作数的类型在上⾯这个列表中排名靠后,那么⾸先要转换为另外⼀个操作数的类型后执⾏运算。
74 0
|
3月前
|
程序员 编译器 C语言
【C语言篇】操作符详解(上篇)
这是合法表达式,不会报错,但是通常达不到想要的结果, 即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到右计算,所以实际执⾏的是下⾯的表达式。
258 0
|
30天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
35 10
|
1月前
|
存储 编译器 C语言
【C语言】简单介绍进制和操作符
【C语言】简单介绍进制和操作符
161 1
|
1月前
|
存储 编译器 C语言
初识C语言5——操作符详解
初识C语言5——操作符详解
179 0
|
3月前
|
C语言
C语言操作符(补充+面试)
C语言操作符(补充+面试)
45 6
|
3月前
|
存储 编译器 C语言
十一:《初学C语言》— 操作符详解(上)
【8月更文挑战第12天】本篇文章讲解了二进制与非二进制的转换;原码反码和补码;移位操作符及位操作符,并附上多个教学代码及代码练习示例
59 0
十一:《初学C语言》—  操作符详解(上)
|
4月前
|
C语言
五:《初学C语言》— 操作符
本篇文章主要讲解了关系操作符和逻辑操作符并附上了多个代码示例
44 1
五:《初学C语言》—  操作符
|
5月前
|
C语言
C语言逻辑操作符的短路问题
C语言逻辑操作符的短路问题
|
5月前
|
算法 C语言
【C语言】:巧用移位操作符,位操作符解决问题
【C语言】:巧用移位操作符,位操作符解决问题
35 0