CSP-J 2022 入门级 第一轮 阅读程序(1) 第16-21题

【题目】

CSP-J 2022 入门级 第一轮 第16题
阅读程序

01 #include <iostream>
02
03 using namespace std;
04
05 int main()
06 {
07     unsigned short x, y;
08     cin >> x >> y;
09     x = (x | x << 2) & 0x33;
10     x = (x | x << 1) & 0x55;
11     y = (y | y << 2) & 0x33;
12     y = (y | y << 1) & 0x55;
13     unsigned short z = x | y << 1;
14     cout << z << endl;
15     return 0;
16 }

假设输入的 x 、 y 均是不超过 15 的自然数,完成下面的判断题和单选题:
判断题
16. 删去第 7 行与第 13 行的 unsigned ,程序行为不变。( )
17. 将第 7 行与第 13 行的 short 均改为 char ,程序行为不变。( )
18. 程序总是输出一个整数“ 0 ”。( )
19. 当输入为“ 2 2 ”时,输出为“ 10 ”。( )
20. 当输入为“ 2 2 ”时,输出为“ 59 ”。( )
单选题
21. 当输入为“ 13 8 ”时,输出为( )。
A. “ 0 ”
B. “ 209 ”
C. “ 197 ”
D. “ 226 ”

【题目考点】

1. 位运算

【解题思路】

本题程序无具体意义,就是执行一系列的位运算

16. 删去第 7 行与第 13 行的 unsigned ,程序行为不变。( )
正确,声明变量时是否加unsigned只影响对该机器数数值的认定,而不影响机器数本身。既然是short类型,这就是一个16位的机器数。所有位运算都是针对机器数的,程序行为不变。
17. 将第 7 行与第 13 行的 short 均改为 char ,程序行为不变。( )
错误,char类型的变量是8位机器数。同样的位运算操作对16位与8位机器数操作的过程不一定是一样的。(例如对机器数10000000左移1位操作,如果是16位机器数,结果为100000000,如果是八位机器数,结果为00000000)。
18. 程序总是输出一个整数“ 0 ”。( )
错误。看一下后面几题,也能看出不可能对于什么输入,输出的都是0,否则后面三题都当做结果是0好了。直接算后面的问题,如果结果不为0,那么该题就是错误的。
19. 当输入为“ 2 2 ”时,输出为“ 10 ”。( )
错误
20. 当输入为“ 2 2 ”时,输出为“ 59 ”。( )
错误
输入x是2,y是2。
计算:x = (x | x << 2) & 0x33;
注意:左移运算符 << 的优先级比按位或 | 的优先级更高。

左移1位是乘2,左移2位是乘4。因此x<<2值为 2 ∗ 4 = 8 2*4=8 24=8
看x的后4位,x为0010,x<<2为1000,二者按位或,即x|x<<2的结果为1010,扩展到8位为00001010
0x33的二进制形式为00110011
二者按位与的结果为:00000010
结果是2。
以上过程列成表格为:

表达式表达式的值(机器数)
x0000 0010
x<<20000 1000
x|x<<20000 1010
0x330011 0011
(x | x << 2) & 0x330000 0010

计算x = (x | x << 1) & 0x55;

表达式表达式的值(机器数)
x0000 0010
x<<10000 0100
x|x<<10000 0110
0x550101 0101
(x | x << 1) & 0x550000 0100

得到x经过计算后的结果为0100。
y与x的初值相同,计算后的结果也应该相同,是0100。
计算z = x | y << 1

表达式表达式的值(机器数)
y0000 0100
y<<10000 1000
x0000 0100
x | y << 10000 1100

z的值为1100,转为十进制是12,因此应该输出12。
因此18,19,20题都选:错误。
21. 当输入为“ 13 8 ”时,输出为( )。
A. “ 0 ”
B. “ 209 ”
C. “ 197 ”
D. “ 226 ”

选择B。
x是13,即1101,y是8,即1000。
计算:x = (x | x << 2) & 0x33;

表达式表达式的值(机器数)
x0000 1101
x<<20011 0100
x|x<<20011 1101
0x330011 0011
(x | x << 2) & 0x330011 0001

计算:x = (x | x << 1) & 0x55;

表达式表达式的值(机器数)
x0011 0001
x<<10110 0010
x|x<<10111 0011
0x550101 0101
(x | x << 1) & 0x550101 0001

计算:y = (y | y << 2) & 0x33;

表达式表达式的值(机器数)
y0000 1000
y<<20010 0000
y|y<<20010 1000
0x330011 0011
(y | y << 2) & 0x330010 0000

计算:y = (y | y << 1) & 0x55;

表达式表达式的值(机器数)
y0010 0000
y<<10100 0000
y|y<<10110 0000
0x550101 0101
(y | y << 1) & 0x550100 0000

计算z = x | y << 1

表达式表达式的值(机器数)
y0100 0000
y<<11000 0000
x0101 0001
x | y << 11101 0001

二进制11100101转为十进制:
2 7 + 2 6 + 2 4 + 2 0 = 128 + 64 + 16 + 1 = 209 2^7+2^6+2^4+2^0=128+64+16+1=209 27+26+24+20=128+64+16+1=209

【答案】

  1. 正确
  2. 错误
  3. 错误
  4. 错误
  5. 错误
  6. B
  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值