信息学奥赛初赛天天练-15-阅读程序-深入解析二进制原码、反码、补码,位运算技巧,以及lowbit的神奇应用

更多资源请关注纽扣编程微信公众号
在这里插入图片描述

1 2021 CSP-J 阅读程序1

阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填 √,错误填×;除特 殊说明外,判断题 1.5 分,选择题 3 分)

源码

#include<stdio.h>
using namespace std;
 
int n;
int a[1000];

int f(int x)//计算二进制1中1的个数
{
	int ret = 0;
    /*
    2 对应二进制 10 ,包含1个1
    10&1=0 ret累加1次退出循环
    3对应二进制101,包含2个1
    101 & 100=100
    100&011=0 ret累加2次退出循环
    */
	for(;x;x&=x-1) ret++;
	return ret;
}
/*
  lowbit 是将 x 转化成二进制数之后,只保留最低位(从右往左数,第一位)的1及其后面的0,截断前面的内容,然后再转成10进制数
  lowbit(8)=8//8对应二进制为:1000 取最右边的1及后面3个0
  lowbit(12)=4//12对应二进制位:1100 取最右边的1及后面3个0
  lowbit(5)=1//5对应二进制为 101 取最右边1及其后面的0
 */
int g(int x)
{
	return x & -x;
}

int main()
{
	scanf("%d",&n);
	for (int i=0;i<n;i++) scanf("%d",&a[i]);
	for(int i=0;i<n;i++)
		printf("%d ",f(a[i])+g(a[i]));
	printf("\n");
	return 0;
}

判断题

1 输入的n等于1001时,程序不会发生下标越界( F )

2 输入的a[i]必须全为正整数,否则程序将陷入死循环( F )

3 当输入为“5 2 11 9 16 10” 时,输出“3 4 3 17 5” ( F )

4 当输入为“1 511998 ”时,输出为"18" ( T )

5 将原码中g函数的定义(13 -16行) 移到main函数的后面,程序可以正常编译运行( F )

单选题

6 当输入为"2 -65536 2147483647"时,输出为 ( B )

A. “65532 33”

B. “65552 32”

C. “65535 34”

D. “65554 33”

2 相关知识点

for 循环语句

重复执行一段代码,直到满足指定条件为止,使用三个表达式控制循环的初始化、退出条件和自变量更新,这3个表达式可以同时出现也可以部分出现

for (初始化表达式; 退出条件; 自变量更新) {
    // 循环体代码
}

示例代码

#include<bits/stdc++.h>
using namespace std;
/*
  for循环语句练习 
*/
int main(){
	//初始化表达式; 退出条件; 自变量更新 同时出现 
	for(int i=0;i<5;i++){
		cout<<i<<" ";
	}
	cout<<endl;
	//初始化表达式 提前定义 
	int i=0; 
	for(;i<5;i++){
		cout<<i<<" ";
	}
	cout<<endl;
	
	//初始化表达式 提前定义  退出条件在循环题 
	i=0; 
	for(;;i++){
		if(i>=5) break; 
		cout<<i<<" ";
	}
	
	cout<<endl;
	
	//初始化表达式 提前定义  退出条件在循环题 自变量在循环体 
	i=0; 
	for(;;){
		if(i>=5) break; 
		cout<<i<<" ";
		i++;
	}
	return 0;
}

原码、反码和补码

1) 机器数

一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用机器数的最高位存放符号,正数为0,负数为1

4  对应二进制 0000 0100
-4 对应二进制 1000 0100

2) 机器数真值

机器数第一位为符号位,所以机器数的形式值不等于真正的数值。所以,将带符号位的机器数对应的真正数值称为机器数的真值

0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

3) 原码

原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值

+2 的原码 0000 0010
-2 的原码 1000 0010

4) 反码

正数的反码是其本身

负数的反码是对原码进行符号位不变,其余各个位取反

+2 的原码 0000 0010   反码 0000 0010
-2 的原码 1000 0010   反码 1111 1101

5) 补码

正数的补码就是其本身

负数的反码是对反码+1

+2 的原码 0000 0010   反码 0000 0010  补码  0000 0010
-2 的原码 1000 0010   反码 1111 1101  补码  1111 1110

位运算

1) 取反运算(~)

是转换2进制后,每1位取反,0变1,1变0

示例代码

//按位取反 ~
#include<bits/stdc++.h>
using namespace std;

int main(){
	/*
	正数的原码,反码,补码都是相同
	4 对应二进制 
	0000 0100 
	按位取反
	1111 1011 计算机是以补码形式存在,需要转换成原码
	-1变成反码
	1111 1010
	按位取反变成原码
	1000 0101 
	第1位是符号位,所以结果是-5 
	*/ 
	int a=4;
	int b=~a;//转二进制补码后按位取反后再转成原码 
	cout<<b; //结果是-5 
	return 0;
}

2) 左移(<<)、右移(>>)

左移

左移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;
}

3) 按位与 (&)

运算规则,按位与的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;
}

4) 按位或 (|)

运算规则,按位或的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;
}

5) lowbit

lowbit(x)是将 x 转化成二进制数之后,只保留最低位(从右往左数,第一位)的1及其后面的0,截断前面的内容,然后再转成10进制数
例如

lowbit(8)=8//8对应二进制为:1000 取最右边的1及后面3个0
lowbit(12)=4//12对应二进制位:1100 取最右边的1及后面3个0
lowbit(5)=1//5对应二进制为 101 取最右边1及其后面的0

示例代码

#include<bits/stdc++.h>
using namespace std;

int g(int x){
	return x & -x;
}

int main(){
	int n=1;
	/*
	  1的补码
	  0000 0001
	  -1的原码
	  1000 0001
	  -1的反码
	  1111 1110
	  -1的补码
	  1111 1111
	  1 & -1
	  0000 0001
	 &1111 1111
	 -----------
	  0000 0001  
	*/ 
	cout<<"g(1)的值是: "<<g(n)<<endl;//输出1
	
	n=3;
	/*
	  3的补码
	  0000 0011
	  -1的原码
	  1000 0011
	  -1的反码
	  1111 1100
	  -1的补码
	  1111 1101
	  1 & -1
	  0000 0001
	 &1111 1101
	 -----------
	  0000 0001  
	*/ 
	cout<<"g(3)的值是: "<<g(n)<<endl;//输出1 
	
	n=8;
		/*
	  3的补码
	  0000 1000
	  -1的原码
	  1000 1000
	  -1的反码
	  1111 0111
	  -1的补码
	  1111 1000
	  1 & -1
	  0000 1000
	 &1111 1000
	 -----------
	  0000 1000  
	*/ 
	cout<<"g(8)的值是: "<<g(n)<<endl;//输出8 
	return 0;
}

6) x&=x-1

x&=x-1 去除二进制补码最后1个1

示例代码

#include<bits/stdc++.h>
using namespace std;
/*
  去除二进制补码最后一个1
  正数 
  9对应补码 0000 1001 
  8对应补码 0000 1000 
  x&=x-1;
  0000 1001 
& 0000 1000 
-------------
  0000 1000
结果为10进制的8
 负数
 -9
 原码  1000 1001
 反码  1111 0110
 补码  1111 0111
 x-1 -9-1=-10
 原码  1000 1010
 反码  1111 0101
 补码  1111 0110
 x&=x-1;
  1111 0111
& 1111 0110 
-------------
  1111 0110 
  比-9的补码 1111 0111少了末尾的1
  补码 1111 0110  对应反码 1111 0101 对应原码 1000 1010 对应十进制-10 
*/ 
int main(){
	int x=9;
	//去除二进制补码最后1个1 
	x&=x-1;
	cout<<x<<endl;//输出 8 
	
	x=-9;
	//去除二进制补码最后1个1 
	x&=x-1;
	cout<<x<<endl;//输出 -10 
	return 0;
}

3 思路分析

判断题

1 输入的n等于1001时,程序不会发生下标越界( F )

分析

a[1000]的下标范围为a[0] - a[999],所以a[1000]会导致越界

2 输入的a[i]必须全为正整数,否则程序将陷入死循环( F )

分析

负数不会进入死循环,负数计算机补码表示

例如 -3

在8位二进制中

原码 1000 0011

反码 1111 1100

补码 1111 1101

对应32位补码是

11111111111111111111111111111101

是31个1

3 当输入为“5 2 11 9 16 10” 时,输出“3 4 3 17 5” ( F )

分析

根据函数作用逐一输入上面5个数计算

输入数据后逐个计算,输出为3 4 3 17 4

f(2)+g(2)=1+2=3

f(2)+g(2)=3+1=4

f(2)+g(2)=2+1=3

f(2)+g(2)=1+16=17

f(2)+g(2)=2+2=4

4 当输入为“1 511998 ”时,输出为"18" ( T )

分析

511998 对应二进制 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0

f(2)+g(2)=16+2=18

5 将原码中g函数的定义(14 -16行) 移到main函数的后面,程序可以正常编译运行( F )

分析

main函数调用的函数必须在main函数前面定义,否则编译会出错

单选题

6 当输入为"2 -65536 2147483647"时,输出为 ( B )

A. “65532 33”

B. “65552 32”

C. “65535 34”

D. “65554 33”

分析

-65536

原码

00000000000000010000000000000000

反码

11111111111111101111111111111111

补码

11111111111111110000000000000000

所以f(-65536)+g(-65536)=16+65536=65552

2147483647 是2^32-1,31个1,最高位是符号位

正数的原码,反码,补码都相同

01111111111111111111111111111111

f(2147483647)+g(2147483647)=31 + 1=32

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/661090.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是访问控制漏洞

什么是AC Bugs&#xff1f; 实验室 Vertical privilege escalation 仅通过隐藏目录/判断参数来权限控制是不安全的&#xff08;爆破url/爬虫/robots.txt/Fuzz/jsfinder&#xff09; Unprotected functionality 访问robots.txt 得到隐藏目录&#xff0c;访问目录 &#xff0c;…

使用Jmeter进行性能测试的基本操作方法

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

长难句打卡5.29

Today, professors routinely treat the progressive interpretation of history and progressive public policy as the proper subject of study while portraying conservative or classical liberal ideas — such as free markets and self-reliance — as falling outsid…

【SPSS】基于因子分析法对水果茶调查问卷进行分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

No input file specified.(‘.user.ini’文件问题宝塔复制到本地,其他情况可跳过)

症状 病因 一般是宝塔直接copy到本地的情况。 宝塔面板中的.user.ini文件是一个重要的配置文件&#xff0c;它主要用于配置PHP运行环境和网站环境。以下是.user.ini文件的主要作用和操作建议&#xff1a; 防止跨目录访问和文件跨目录读取。这是.user.ini文件的主要作用之一&a…

采用Java+ SpringBoot+ IntelliJ+idea开发的ADR药物不良反应监测系统源码

采用Java SpringBoot IntelliJidea开发的ADR药物不良反应监测系统源码 ADR药物不良反应监测系统有哪些应用场景&#xff1f; ADR药物不良反应监测系统有哪些应用场景&#xff1f; ADR药物不良反应监测系统具有广泛的应用场景&#xff0c;以下是一些主要的应用场景&#xff1a…

AVL树的模拟实现

我们上期提到了二叉搜索树&#xff0c;只是简单的讲了一下原理&#xff0c;那么今天我们就讲一下AVL树。 目录 AVL树的概念AVL树的实现AVL树的架构insert插入引用pair对象引进parent指针仅插入数据调节平衡因子情况1&#xff1a;插入在父亲的右边&#xff0c;父亲的平衡因子后…

如何应对Android面试官 -> 玩转 Fragment

前言 本章主要讲解下 Framgent 的核心原理&#xff1b; 基础用法 线上基础用法&#xff0c;其他的可以自行百度 FragmentManager manager getSupportFragmentManager(); FragmentTransaction transaction manager.beginTransaction(); transaction.add(R.id.contentlayout,…

100个投资者99个选择使用这款EA,WeTrade发现1个事实

为什么100个投资者会有99个选择使用这款EA&#xff0c;是因为这款EA能提供两个版本吗?是因为能控制风险吗?都不是&#xff0c;WeTrade发现1个事实才是这么多投资者选择的原因&#xff0c;那就是能实现100%的盈利率。 我们都知道外汇狙击手EA提供两种版本&#xff0c;分别是标…

2018 年山东省职业院校技能大赛高职组“信息安全管理与评估”赛项任务书

2018年山东省职业院校技能大赛高职组 “信息安全管理与评估”赛项任务书 赛项时间 8:30-13:00&#xff0c;共计4小时30分钟&#xff0c;含赛题发放、收卷时间。 赛项信息 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 平台搭建与安全设备配置防护 …

云原生网关 MSE-Higress

云原生网关 MSE-Higress 什么是云原生网关MSEMSE测评产品文档产品能力产品控制台 MSE与其他网关 什么是云原生网关MSE 在体验云原生网关 MSE-Higress功能之前&#xff0c;先了解一下什么是云原生网关 MSE&#xff0c;简单的说就是MSE就是遵循开源 Ingress/Gateway API 标准的下…

kubernetes(Jenkins、kubernetes核心、K8s实战-KubeSphere、)

文章目录 1. Jenkins1.1. 概述1.1.1. 简单部署1.1.2. 自动化部署1.1.3. DevOps概述1.1.4. CI/CD概述 1.2. jenkins介绍及安装1.2.1. 安装1.2.2. 解锁jenkins1.2.3. 安装推荐插件1.2.4. 创建管理员用户1.2.5. 升级jenkins版本1.2.6. 安装额外插件blue ocean1.2.7. jenkins界面说…

[vue3后台管理二]首页和登录测试

[vue3后台管理二]首页和登录测试 1 修改main.js import ./assets/main.cssimport { createApp } from vue import App from ./App.vue import router from ./router createApp(App).use(router).mount(#app)2 路由创建 import {createRouter, createWebHistory} from vue-ro…

装机必备——截图工具Snipaste安装教程

装机必备——截图工具Snipaste安装教程 软件下载 软件名称&#xff1a;Snipaste2.7 软件语言&#xff1a;简体中文 软件大小&#xff1a;15.37M 系统要求&#xff1a;Windows7或更高&#xff0c; 32/64位操作系统 硬件要求&#xff1a;CPU2GHz &#xff0c;RAM2G或更高 下载通…

论文笔记 Explicit Visual Prompting for Low-Level Structure Segmentations

通俗地解释视觉中的prompt 在视觉中的“prompt”&#xff08;提示&#xff09;可以用一种比较通俗的方式来理解&#xff1a; 什么是视觉中的提示&#xff1f; 想象一下&#xff0c;你有一个已经接受过大量训练的超级助手&#xff08;类似于预训练的模型&#xff09;&#xf…

vscode:如何解决”检测到include错误,请更新includePath“

vscode:如何解决”检测到include错误&#xff0c;请更新includePath“ 前言解决办法1 获取includePath路径2 将includePath路径添加到指定文件3 保存 前言 配置vscode是出现如下错误&#xff1a; 解决办法 1 获取includePath路径 通过cmd打开终端&#xff0c;输入如下指令&a…

C++之vector

1、标准库的vector类型 2、vector对象的初始化 3、vector常用成员函数 #include <vector> #include <algorithm> #include <iostream> using namespace std;typedef vector<int> INTVEC;// 普通方法 //void showVec(const INTVEC& vec) // 这边如…

⌈ 传知代码 ⌋ YOLOv9最新最全代码复现

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

一款高级管理控制面板主题!【送源码】

AdminLTE是一个完全响应的管理模板。基于Bootstrap5框架和JavaScript插件。高度可定制&#xff0c;易于使用。适用于从小型移动设备到大型桌面的多种屏幕分辨率。AdminLTE 是一个基于Bootstrap 3.x的免费高级管理控制面板主题。 https://github.com/almasaeed2010/AdminLTE —…