C语言习题~day13

简介: C语言习题

1.将十进制数-5转换为8位二进制补码时,其表示为:

A.00000101


B.10000010


C.11111011


D.11111101


将 5 的绝对值转换为二进制数,得到 00000101。


反转二进制数的每一位,得到 11111010。


将反转后的二进制数加 1,得到补码表示。


11111010 + 1 = 11111011


如果需要将补码表示转换回原始的负数,可以将补码再次取反,并加上负号。但在这种情况下,我们已经得到了 8 位二进制补码的表示。


因此,十进制数 -5 的 8 位二进制补码表示为 11111011

2.原码、反码、补码说法错误的是( )

A.一个数的原码是这个数直接转换成二进制

B.反码是原码的二进制符号位不变,其他位按位取反

C.补码是反码的二进制加1

D.原码、反码、补码的最高位是0表示负数,最高位是1表示正数

ABC正确

D关于符号位的描述说反了:0表示正数,1表示负数

3.假设在C语言中,有两个整数变量x = 9y = 3,表达式x ^ y的结果是什么?

A.6

B.12

C.10

D.0

在 C 语言中,使用 ^ 运算符表示按位异或(XOR)运算。按位异或运算是将两个操作数的对应位进行异或操作,如果两个对应位的值不同,则结果为 1,如果两个对应位的值相同,则结果为 0。


对于给定的表达式 x ^ y,其中 x = 9 和 y = 3,我们可以将它们分别转换为二进制数:


x = 9 的二进制表示为 1001 y = 3 的二进制表示为 0011


因此,表达式 x ^ y 的结果是 1010,转换为十进制数为 10。

4.假设在C语言中,有两个整数变量a = 12b = 5,表达式a & b的结果是什么?

A.0

B.4

C.5

D.12

a = 12 的二进制表示为 1100 b = 5 的二进制表示为 0101

按位与运算如下所示:

1100 & 0101

0100

因此,表达式 a & b 的结果是 0100,转换为十进制数为 4。

5.在C语言中,算术右移运算符(>>)用于将一个数的各个位向右移动指定的位数,空出的位用什么填充?

A.0

B.1

C.符号位

D.随机值

C

6.左移运算符(<<)将一个数的各个位向左移动指定的位数,空出的位用什么填充?

A.0

B.1

C.符号位

D.随机值

A

7.下面哪个是位操作符:( )

A.&

B.&&

C.||

D.!

A. & 是按位与操作符,正确

B. && 是逻辑与,不是按位与,错误

C. || 是逻辑或,错误

D. ! 是逻辑反操作符,错误

8.交换两个变量(不创建临时变量)

#include <stdio.h>
int main()
{
  int a = 10;
    int b = 20;
    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;

9.写一个函数返回参数二进制中 1 的个数。比如: 15    0000 1111    4 个 1

/*
方法一:
思路:
循环进行以下操作,直到n被缩减为0:
   1. 用该数据模2,检测其是否能够被2整除
   2. 可以:则该数据对应二进制比特位的最低位一定是0,否则是1,如果是1给计数加1
   3. 如果n不等于0时,继续1
*/
int NumberOf1(int n)
{
  int count = 0;
  while(n)
  {
    if(n%2==1)
      count++;
    n = n/2;
  }
  return count;
}
 
 
/*
上述方法缺陷:进行了大量的取模以及除法运算,取模和除法运算的效率本来就比较低。
方法二思路:
一个int类型的数据,对应的二进制一共有32个比特位,可以采用位运算的方式一位一位的检测,具体如下
*/
int NumberOf1(unsigned int n)
{
  int count = 0;
  int i = 0;
  for(i=0; i<32; i++)
  {
    if(((n>>i)&1) == 1)
      count++;
  }
  return count;
}
 
 
/*
方法二优点:用位操作代替取模和除法运算,效率稍微比较高
  缺陷:不论是什么数据,循环都要执行32次
  
方法三:
思路:采用相邻的两个数据进行按位与运算
举例:
9999:‭10 0111 0000 1111‬
第一次循环:n=9999   n=n&(n-1)=9999&9998= 9998
第二次循环:n=9998   n=n&(n-1)=9998&9997= 9996
第三次循环:n=9996   n=n&(n-1)=9996&9995= 9992
第四次循环:n=9992   n=n&(n-1)=9992&9991= 9984
第五次循环:n=9984   n=n&(n-1)=9984&9983= 9728
第六次循环:n=9728   n=n&(n-1)=9728&9727= 9216
第七次循环:n=9216   n=n&(n-1)=9216&9215= 8192
第八次循环:n=8192   n=n&(n-1)=8192&8191= 0
可以观察下:此种方式,数据的二进制比特位中有几个1,循环就循环几次,而且中间采用了位运算,处理起来比较高效
*/
int NumberOf1(int n)
{
  int count = 0;
  while(n)
  {
    n = n&(n-1);
    count++;
  }
  return count;
}

10.编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?

输入例子:1999 2299    输出例子:7

/*
思路:
1. 先将m和n进行按位异或,此时m和n相同的二进制比特位清零,不同的二进制比特位为1
2. 统计异或完成后结果的二进制比特位中有多少个1即可
*/
#include <stdio.h>
int calc_diff_bit(int m, int n)
{
  int tmp = m^n;
  int count = 0;
  while(tmp)
  {
    tmp = tmp&(tmp-1);
    count++;
  }
  return count;
}
 
 
int main()
{
 int m,n;
 while(scanf("%d %d", &m, &n) == 2)
 {
     printf("%d\n", calc_diff_bit(m, n));
 }
 return 0;
}


目录
相关文章
TU^
|
6月前
|
存储 C语言
C语言习题~day35
C语言习题~day35
TU^
31 1
|
4月前
|
机器学习/深度学习 C语言
【C语言篇】递归详细介绍(基础概念习题及汉诺塔等进阶问题)
要保持最小的步数,每一次汉诺塔问题(无论是最初还是递归过程中的),如果此时初始柱盘子数为偶数,我们第一步是把最上面的盘子移动到中转柱,如果为奇数,我们第一步则是将其移动到目标柱。
96 0
【C语言篇】递归详细介绍(基础概念习题及汉诺塔等进阶问题)
TU^
|
6月前
|
编译器 C语言
C语言习题~day31
C语言习题~day31
TU^
24 2
TU^
|
6月前
|
算法 程序员 C语言
C语言习题~day36
C语言习题~day36
TU^
43 1
TU^
|
6月前
|
存储 C语言
C语言习题~day34
C语言习题~day34
TU^
35 1
TU^
|
6月前
|
算法 C语言
C语言习题~day33
C语言习题~day33
TU^
31 1
TU^
|
6月前
|
C语言
C语言习题~day32
C语言习题~day32
TU^
19 1
TU^
|
6月前
|
C语言
C语言习题~day30
C语言习题~day30
TU^
24 1
TU^
|
6月前
|
自然语言处理 C语言 C++
C语言习题~day29
C语言习题~day29
TU^
25 1
TU^
|
6月前
|
存储 C语言
C语言习题~day28
C语言习题~day28
TU^
22 1