C语言习题~day13

 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值