信息学奥赛初赛天天练-27-CSP-J2022阅读程序位运算、数据类型范围、进制转换攻略
PDF文档公众号回复关键字:20240612
![](https://img2022.cnblogs.com/blog/404484/202211/404484-20221123185906168-1425738362.png)
2022 CSP-J 阅读程序1
阅读程序(判断题1.5分 选择题3分 共计40分 )
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"
2 相关知识点
位运算
1) 左移(<<)、右移(>>)
左移
左移1位,所有位都左移,末尾补0
右移
右移1位,所有位都右移,首尾补0
示例代码
//左移 << 右移 >>
#include<bits/stdc++.h>
using namespace std;
int main(){
int a=3;
/*
3 对应二进制
0000 0011
左移1位,所有位都左移,末尾补0
0000 0110
此时对应二进制转十进制为6
*/
int b=3<<1;
cout<<"b的值为:"<<b<<endl;//所以b的值为6
int c=8;
/*
8 对应二进制
0000 1000
右移1位,所有位都右移,首尾补0
0000 0100
此时对应二进制转十进制为4
*/
int d=c>>1;
cout<<"d的值为:"<<d;//所以d的值为4
return 0;
}
2) 按位与 (&)
运算规则,按位与的2个位同时为1时,结果为1,否则为0
示例代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int a=5;
int b=6;
/*
5对应的二进制为
0000 0101
6对应的二进制为
0000 0110
所以 5 & 6
0000 0101
& 0000 0110
-------------
0000 0100
转对应10进制为4
*/
int c=a&b;
cout<<"c的值为:"<<c; //输出c的值为4
return 0;
}
3) 按位或 (|)
运算规则,按位或的2个位其中有1个为1,结果为1,否则为0
示例代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int a=5;
int b=6;
/*
5对应的二进制为
0000 0101
6对应的二进制为
0000 0110
所以 5 & 6
0000 0101
| 0000 0110
-------------
0000 0111
转对应111进制为7
*/
int c=a|b;
cout<<"c的值为:"<<c; //输出c的值为7
return 0;
}
4) 位运算符优先级
/*
左移 右移 > 按位与 > 异或 > 或
<< >> > & > ^ > |
*/
5) unsigned 关键字
用于声明无符号整数类型。无符号整数类型只能表示非负整数,即它们的值总是大于或等于零
例如
short是16为二进制组成,第1位是符号位,表示范围-32768~32767之间
unsigned short是16为二进制组成,无符号位, 表示范围0~65535之间
#include<bits/stdc++.h>
using namespace std;
/*
无符号关键字
short是16为二进制组成,第1位是符号位,表示范围-32768~32767之间
unsigned short是16为二进制组成,无符号位, 表示范围0~65535之间
*/
int main(){
short a=32769;//超出了short的范围
unsigned short b=32769;//在范围内可以正常表示
cout<<"a的值为:"<<a<<endl; //输出不正确
cout<<"b的值为:"<<b<<endl;
return 0;
}
/*
a的值为:-32767
b的值为:32769
*/
6) 进制转换
十六进制转二进制
16进制1位对应二进制4位,逐位进行转换
(A4)H = (1010 0100)B =(10100100)B
3 思路分析
假设输入的x、y均是不超过15的自然数,完成下面判断题和选择题
判断题
16.删去第7行与第13行的unsigned,程序行为不变 ( T )
分析
//x、y均是不超过15的自然数,观察程序第9行
/*
x = (x | x<<2) & 0x33;
x最大为15,对应二进制1111
x<<2对应二进制 111100
x | x<<2= 1111 | 111100 = 111111 //此时和0x33与最大,因为x比0x33小,x二进制对应位不是1的话&0x33 对应位的1会变0
0x33对应二进制00110011
//(x | x<<2) & 0x33 =111111 & 00110011 = 00110011 = 0x33
*/
//第9行执行完x最大为0x33 =00110011
(x | x<<1)=00110011|01100110=01110111
(x | x<<1) & 0x55=01110111 & 01010101=01010101=0x55 //此时也是最大值,因为y的值比0x55小,x二进制对应位不是1的话&0x55对应位的1会变0
//第11行和12行同9和10行,所以输入x和y都为15时最大
//执行13行 x | y << 1;
01010101|10101010=11111111=255
unsigned short是16为二进制组成,无符号位, 表示范围0~65535之间
去除unsigned后,short是16为二进制组成,第1位是符号位,表示范围-32768~32767之间
满足最大值255,所以没影响
17.将第7行与第13行的short均改为char,程序行为不变( F )
分析
unsigned char的取值范围0~255,根据16题最大值是255,取值范围满足
cout<<z<<endl;//z是char类型,输出的是255对应的ascii码,不能正确输出255数字
所以错误
18.程序总是输出一个整数"0"( F )
分析
程序不是总输出0
例如 16题中,x=15,y=15时,输出结果为255
19.当输入为"2 2"时,输出为"10"( F )
分析
//x=2时,执行 (x | x<<2)
0000 0010 |0000 1000 =0000 1010
//执行 x & 0x33
//0x33 =00110011
0000 1010 & 0011 0011=0000 0010
//执行 (x | x<<1)
0000 0010 | 0000 0100=0000 0110
//执行 x & 0x55 //0x55=01010101
0000 0110 & 0101 0101=0000 0100=4
//对y进行操作 y=2 和x操作相同
y=4
//执行 z = x | y << 1;
// 执行 y << 1
y=0000 0100<<1=0000 1000
z=x | y=0000 0100 | 0000 1000=0000 1100=12
输出结果为12,所以本题输出10是错误的
20.当输入为"2 2"时,输出为"59" ( F )
分析
参考19题,输出结果应该是12,输出59结果是错误的
单选题
21.当输入为"13 8"时,输出为( )
A. "0" B. "209" C "197" D. "226"
分析
//x=13,执行 (x | x<<2)
0000 1101 | 0011 0100 =0011 1101
//执行 x & 0x33
//0x33 =00110011
0011 1101 & 0011 0011=0011 0001
//执行 (x | x<<1)
0011 0001 | 0110 0010=0111 0011
//执行 x & 0x55 //0x55=01010101
0111 0011 & 0101 0101=0101 0001=81
x=0101 0001=81
//y=8,执行 (x | x<<2)
0000 1000 |0010 0000 =0010 1000
//执行 x & 0x33
//0x33 =00110011
0010 1000 & 0011 0011=0010 0000
//执行 (x | x<<1)
0010 0000 | 0100 0000=0110 0000
//执行 x & 0x55 //0x55=01010101
0110 0000 & 0101 0101=0100 0000=64
y=0100 0000=64
//执行 z = x | y << 1;
// 执行 y << 1
y=0100 0000<<1=1000 0000
z=x | y=0101 0001 | 1000 0000=1101 0001 =128 + 64 +16 +1 = 209
所以选B
作者:newcode 更多资源请关注纽扣编程微信公众号
从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习