信息学奥赛初赛天天练-27-CSP-J2022阅读程序位运算、数据类型范围、进制转换攻略

PDF文档公众号回复关键字:20240612

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
posted @ 2024-06-12 20:53  new-code  阅读(7)  评论(0编辑  收藏  举报