信息学奥赛初赛天天练-88-CSP-S2023阅读程序1-数据类型、unsigned 关键字、二进制、位运算、左移、右移、异或运算
PDF文档公众号回复关键字:20240913
2023 CSP-S 阅读程序1
判断题正确填 √,错误填 ⨉ ;除特殊说明外,判断题 1.5 分,选择题 3 分,共计 40 分)
01 #include <iostream>
02 using namespace std;
03
04 unsigned short f(unsigned short x) {
05 x ^= x << 6;
06 x ^= x >> 8;
07 return x;
08 }
09 int main() {
10 unsigned short x;
11 cin >> x;
12 unsigned short y = f(x);
13 cout << y << endl;
14 return 0;
15 }
假设输入的 x 是不超过 65535的自然数,完成下面的判断题和单选题
判断题
1 当输入非零时,输出一定不为零 ( )
2 (2 分)将 f
函数的输入参数的类型改为 unsigned int
,程序的输出不变 ( )
3 当输入为 65535
时,输出为 63
( )
4 当输入为 1
时,输出为 64
( )
单选题
5 当输入为 512
时,输出为 ( )
6 当输入为 64
时,执行完第 5 行后 x
的值为 ( )
2 相关知识点
1) 常用数据类型
数据类型 | 描述 | 取值范围 |
---|---|---|
char |
字符型 | -128 到 127 或 0 到 255(取决于是否是有符号的) |
short |
短整型 | -32,768 到 32,767 |
int |
整型 | -2,147,483,648 到 2,147,483,647 |
long |
长整型 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
long long |
更长的整型 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
2) 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
*/
3) 二进制
二进制(Binary)是一种计数系统,它只使用两个数字:0和1。它是计算机科学中最基本的数制,因为计算机内部的所有信息都是以二进制形式存储和处理的
在二进制系统中,每一位的权重是2的幂次方
最右边的位(最低位)的权重是2^0 = 1
从右向左数第二位的权重是2^1 = 2
从右向左数第三位的权重是2^2 = 4
以此类推
二进制数的表示方法是从右向左,每一位的数字乘以其对应的权重,然后将所有的结果相加。例如,二进制数1101转换为十进制数的计算过程如下
1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 8 + 4 + 0 + 1 = 13
4) 位运算
左移(<<)、右移(>>)
左移
左移1位,所有位都左移,末尾补0
右移
右移1位,所有位都右移,首尾补0
//左移 << 右移 >>
#include<bits/stdc++.h>
using namespace std;int main(){int a=3;/*3 对应二进制 0000 0011 左移1位,所有位都左移,末尾补00000 0110此时对应二进制转十进制为6 */int b=3<<1; cout<<"b的值为:"<<b<<endl;//所以b的值为6 int c=8;/*8 对应二进制 0000 1000 右移1位,所有位都右移,首尾补00000 0100此时对应二进制转十进制为4 */int d=c>>1;cout<<"d的值为:"<<d;//所以d的值为4return 0;
}
异或运算
异或运算(XOR)是一种基本的数学运算符,应用于逻辑运算,其数学符号为“⊕”,计算机符号为“xor”
异或运算的运算法则为:如果两个值不相同,则异或结果为1;如果两个值相同,则异或结果为0
//示例
2 xor 3 = 1
具体过程如下
2 对应二进制 0010
3 对应二进制 001100100011
xor
----------0001
C++语言中 异或符号为 ^
p^=1等价p=p^1p为0时 p^1=0^1=1
具体过程如下
0对应二进制为 0000
1对应二进制为 000100000001
xor
----------0001p为1时 p^1=1^1=0
具体过程如下
1对应二进制为 000100010001
xor
----------0000
3 思路分析
假设输入的 x 是不超过 65535的自然数,完成下面的判断题和单选题
判断题
1 当输入非零时,输出一定不为零 ( T )
分析
异或运算规则可知,只要异或前后的数字不同就为1
short总共16位,先左移6位,右边补0,左边溢出,其中12位不能为1,如果为1则输出不为0
又右移8位,左边补0,右边溢出,涉及16位都不能为1
所以只有输入为0,输出才为0
因此正确
2 (2 分)将 f
函数的输入参数的类型改为 unsigned int
,程序的输出不变 ( F )
分析
unsigned int 为无符号4个字节
unsigned short 为无符号2个字节
如下代码,如果2个字节对应16位二进制short时,会有溢出丢失一些位1的情况
int为4个字节对应32位二进制short时,不会溢出,因此输出结果可能会变
05 x ^= x << 6;
06 x ^= x >> 8;
3 当输入为 65535
时,输出为 63
( T )
分析
输入65535时,对应二进制为16位二进制都是1
1111111111111111
左移6位
1111111111000000左移前和左移后进行异或运算1111111111111111
^ 1111111111000000
-------------------0000000000111111右移8位0000000000111111>>8=0000000000000000右移前和右移后进行异或运算0000000000111111
^ 0000000000000000
-------------------0000000000111111
转换十进制
2^5+2^4+2^3+2^2+2^1+2^0=2^6-1=63
所以正确
4 当输入为 1
时,输出为 64
( F )
分析
输入1时,对应二进制为1
000000001
左移6位
1000000左移前和左移后进行异或运算1000000
^ 0000001
-------------------1000001右移8位1000001>>8=0000000右移前和右移后进行异或运算1000001
^ 0000000
-------------------1000001
转换十进制
2^6+2^0=2^6+1=65
所以错误
单选题
5 当输入为 512
时,输出为 ( B )
A 33280
B 33410
C 33106
D 33346
分析
512对应的二进制为
1000000000
左移6位
1000000000000000左移前和左移后进行异或运算1000000000000000
^ 1000000000
-------------------1000001000000000
右移8位 10000010右移前和右移后进行异或运算1000001000000000
^ 10000010
-------------------1000001010000010对上面二进制转换10进制
2^15+2^9+2^7+2^1
=32768+512+128+2
=33410
所以选B
6 当输入为 64
时,执行完第 5 行后 x
的值为 ( D )
A 8256
B 4130
C 4128
D 4160
分析
64对应的二进制为
1000000
左移6位
1000000000000左移前和左移后进行异或运算1000000000000
^ 1000000
---------------1000001000000对上面二进制转换10进制
2^12+2^6
=4096+64
=4160
所以选D