第三十三章 使用Redux管理状态

news2024/11/18 9:20:29

  Redux(全称为Redux)是一个基于状态管理的JavaScript库,它可以用来构建可重用的、可维护的代码。Redux主要用于处理复杂的应用程序中的状态管理,它能够自动地处理应用程序中的更改,并在需要时更新视图。

  Redux使用一种被称为“状态树”的数据结构来管理应用程序的状态。状态树中的每个节点都代表应用程序中的一个状态,而每个状态都可以有自己的副本和父节点。当应用程序中的某个状态发生更改时,它会通过一个被称为“动作”的API来更新状态树,并触发有关的副作用。这意味着,当一个部分的状态更改时,不会影响其他部分。

  Redux使用一个中央控制器来协调应用程序中的所有状态更改。这个控制器可以监听所有的动作,并根据需要更改状态。Redux也提供了一些工具,如树形状态视图和状态转换器,来帮助开发人员处理复杂的状态管理。

  总的来说,Redux是一种非常强大和灵活的库,可以用来构建复杂的应用程序。它能够使开发人员专注于应用程序的逻辑,并帮助他们更轻松地管理应用程序中的状态。

具体详情请参考:Redux 中文官网


什么情况下使用Redux?

Redux 通常用于处理复杂的应用程序,特别是那些具有大量状态和复杂逻辑的应用程序。以下是一些 Redux 可能适合您的应用程序的示例:

  • 您的应用程序具有复杂的路由和状态管理逻辑。
  • 您需要处理大量的状态和更改,并且不希望在代码中硬编码它们。
  • 您需要更好地组织和管理您的状态和副作用。
  • 您需要一种方式来组合和重用不同的状态和动作。

当您考虑使用 Redux 时,需要确定您的应用程序是否适合使用 Redux。如果您的应用程序符合上述条件,那么 ReducerMiddlewareother 组件可以帮助您更轻松地管理应用程序的状态和逻辑。


Redux的工作原理

Redux 的工作原理是通过将应用程序的状态和动作拆分成独立的组件来实现的。在 Reducer 中,您可以使用一组函数来更改应用程序的状态。每个函数都接收一个 state 和一个 action,并返回一个新的 stateRedux 通过组合这些 state 来控制应用程序的状态。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HeKPRhDI-1684308971073)(D:\GeniusNotes\ReactNote\react_staging\img\redux原理图.png)]

Redux 中,还有一些中间件(称为 Connect),它们用于协调 Redux 中的组件。Connect 可以帮助您将应用程序的不同部分连接在一起,并提供一些功能,如数据流和状态管理。 当 Redux 中的某个组件触发一个动作时,它会通过 Action 来通知 Redux。这个 Action 可以被 Redux 中的其他组件所读取和处理。Redux 还提供了一些其他的工具和库,如 ConnectHooks Reducer,来帮助开发人员处理复杂的应用程序逻辑。

Redux的三个核心概念

  1. ActionAction 是一种数据类型,它表示一个状态更改操作。Action 可以被 Redux 中的所有组件读取和处理。Action 可以包含任何类型的数据,例如字符串、数字或映射。
  2. ReducerReducerRedux 中用于修改 state 的组件。Reducer 接收一个 state 和一个 action,并返回一个 new stateReducer 的作用是通过更改状态来控制 Redux 中的应用程序逻辑。Reducer 通常由一组函数组成,这些函数接收一个 state 和一个 action,并返回一个 new state
  3. StoreStoreRedux 中用于存储和管理 state 和动作的组件。Store 是一个全局的对象,它可以存储应用程序的所有 state 和动作。Store 可以被 Redux 中的其他组件所读取和处理。Store 还负责协调 Redux 中的所有 state 的更改。

通过求和案例循序渐进了解Redux

以下是案列的图示:

在这里插入图片描述

该组件(包含一个下拉框,四个功能按钮)功能很简单:

  • 选择下拉框,选择要加减的具体数值
  • 点击按钮+,将下拉框的数值进行相加
  • 点击按钮-,将下拉框的数值进行相减
  • 点击按钮当前求和为奇数为,当和是奇数的时候才将下拉框的值进行相加,否则不操作
  • 点击按钮异步加,点击按钮之后,隔一段时间才将下拉框的值进行相加

1、使用普通的react程序实现该功能

文件:components/Count/index.jsx

import React, { Component } from 'react'

export default class Count extends Component {
  state = { count: 0 }

  increment = () => {
    // 普通加
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、获取原来状态里面的值
    const { count } = this.state

    // 3、进行计算并更新状态值
    this.setState({ count: count + value * 1 })

  }

  decrement = () => {
    // 普通减
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、获取原来状态里面的值
    const { count } = this.state

    // 3、进行计算并更新状态值
    this.setState({ count: count - value * 1 })
  }

  incrementIfOdd = () => {
    // 当前求和为奇数为

    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、获取原来状态里面的值
    const { count } = this.state

    // 3、进行计算并更新状态值
    if (store.getState() % 2 !== 0) {
      this.setState({ count: count + value * 1 })
    }
  }

  incrementAsync = () => {
    // 异步加
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、获取原来状态里面的值
    const { count } = this.state

    // 3、进行计算并更新状态值
    setTimeout(() => {
     this.setState({ count: count + value * 1 })
    }, 500)
  }

  render() {
    return (
      <div>
        <h1>当前求和为:{this.state.count}</h1>
        <select ref={(c) => (this.selectNumber = c)}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        &nbsp;
        <button onClick={this.increment}>+</button>&nbsp;
        <button onClick={this.decrement}>-</button>&nbsp;
        <button onClick={this.incrementIfOdd}>当前求和为奇数为</button>&nbsp;
        <button onClick={this.incrementAsync}>异步加</button>&nbsp;
      </div>
    )
  }
}

文件:App.jsx

import React, { Component } from 'react'
import Count from './components/Count'


export default class App extends Component {
  render() {
    return (
      <div>
        <Count/>
      </div>
    )
  }
}

以上代码就是通过普通的state实现的案例功能。


2、Redux精简版改进求和案例

  • 步骤1:安装依赖包
npm i redux
  • 步骤2:创建文件:redux/store.js
/** 该文件专门用于暴露store对象,整个应用只有一个store对象 */
// 引入createStore,专门用于创建redux中最为核心的store对象
import { createStore } from 'redux'
// 引入为Count组件服务的reducer
import countReducer from './count_reducer'
// 暴露store
export default createStore(countReducer)
  • 步骤3:创建文件:redux/count_reducer.js
/**
 * 1、该文件是用于创建一个为count组件服务的reducer,reducer的本质就是一个函数
 * 2、reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action)
 */
const initCount = 0  // 当reducer做初始化的时候,将初始值undefined改为0
export default function countReducer( preState = initCount, action) {
  // 从action对象中获取type和data
  const { type, data } = action;
  // 根据type类型,如何加工数据
  switch (type) {
    case 'increment': // 如果是加,使用以下逻辑加工数据
      return preState + data;
    case 'decrement': // 如果是减,使用以下逻辑加工数据
    return preState - data;
    default:
      return preState ;
  }
}
  • 步骤4:修改Count组件逻辑
import React, { Component } from 'react'
import store from '../../redux/store' // 引入store

export default class Count extends Component {
  // state = { count: 0 } // 使用了redux的状态后,就不需要组件内部的state了

  componentDidMount() {
    // 监测redux中状态的变化,只要变化,就调用render
    store.subscribe(()=>{
      this.setState({}) // 当调用这个方法后,页面才会更新
    })
  }

  increment = () => {
    // 普通加
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、进行计算并更新状态值,通知redux执行相加逻辑
    store.dispatch({type:'increment',data: value * 1})
  }

  decrement = () => {
    // 普通减
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、进行计算并更新状态值,通知redux执行相减逻辑
    store.dispatch({type:'decrement',data: value * 1})
  }

  incrementIfOdd = () => {
    // 当前求和为奇数为
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、进行计算并更新状态值
    if (store.getState() % 2 !== 0) {
      // 通知redux执行相加逻辑
      store.dispatch({type:'increment',data: value * 1})
    }
  }

  incrementAsync = () => {
    // 异步加
    // 1、获取用户选择的值
    const { value } = this.selectNumber
    
    // 2、进行计算并更新状态值
    setTimeout(() => {
      // 通知redux执行相加逻辑
      store.dispatch({type:'increment',data: value * 1})
    }, 500)
  }

  render() {
      // store.getState(),这个API用于获取redux的状态
    return (
      <div>
        <h1>当前求和为:{store.getState()}</h1>
        <select ref={(c) => (this.selectNumber = c)}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        &nbsp;
        <button onClick={this.increment}>+</button>&nbsp;
        <button onClick={this.decrement}>-</button>&nbsp;
        <button onClick={this.incrementIfOdd}>当前求和为奇数为</button>&nbsp;
        <button onClick={this.incrementAsync}>异步加</button>&nbsp;
      </div>
    )
  }
}

  • 步骤5:优化redux的监听

为了让整个应用都监听redux的变化,我们需要将订阅redux变化的逻辑写到入口文件中

文件:index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from './redux/store'

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
// 监听全局redux,一但发生改变就会更新页面
store.subscribe(()=> {
    root.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>
	);
})
  • 小节总结

(1). 去除Count组件自身的状态

(2). src下建立:

-src

|----redux

   |----store.js

   |----count_reducer.js

(3).store.js:

​ 1).引入redux中的createStore函数,创建一个store

​ 2).createStore调用时需要传入一个为其服务的reducer

​ 3).记得暴露store对象

(4).count_reducer.js:

​ 1). reducer的本质是一个函数,接收:preState,action,返回加工后的状态

​ 2). reducer有两个作用:初始化状态,加工状态

​ 3). reducer被第一次调用时,是store自动触发的,传递的preStateundefined,传递的action是:{type:'@@REDUX/INIT_a.1.2.3'}

(5).在index.js中监测store中状态的改变,一旦发生改变重新渲染<App/>

备注:redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写。


3、Redux完整版求和案例

完整版比精简版多了几个文件:constant.jscount_action.js

  • 定义常量文件:constant.js,便于管理
// 该模块是用于定义action对象的type类型的常量值
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
  • 定义管理action对象的文件,层次分明
// 该文件专门为Count组件生成action对象
import {INCREMENT,DECREMENT} from './constant'
export const createIncrementAction = data => ({ type: INCREMENT,data})

export const createDecrementAction = data => ({ type: DECREMENT,data})

  • 完善组件内容
import React, { Component } from 'react'
import store from '../../redux/store'
// 引入actioncreator,专门用于创建action对象
import { createIncrementAction, createDecrementAction} from '../../redux/count_action'
export default class Count extends Component {

  increment = () => {
    // 普通加
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、进行计算并更新状态值
    // 通知redux更改状态
    store.dispatch(createIncrementAction(value * 1))
  }

  decrement = () => {
    // 普通减
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、进行计算并更新状态值
    // 通知redux更改状态
    store.dispatch(createDecrementAction(value * 1))
  }

  incrementIfOdd = () => {
    // 当前求和为奇数为
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、进行计算并更新状态值
    if (store.getState() % 2 !== 0) {
      // 通知redux更改状态
      store.dispatch(createIncrementAction(value * 1))
    }
  }

  incrementAsync = () => {
    // 异步加
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、进行计算并更新状态值
    setTimeout(() => {
      // 通知redux更改状态
      store.dispatch(createIncrementAction(value * 1))
    }, 500)
  }

  render() {
    return (
      <div>
        <h1>当前求和为:{store.getState()}</h1>
        <select ref={(c) => (this.selectNumber = c)}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        &nbsp;
        <button onClick={this.increment}>+</button>&nbsp;
        <button onClick={this.decrement}>-</button>&nbsp;
        <button onClick={this.incrementIfOdd}>当前求和为奇数为</button>&nbsp;
        <button onClick={this.incrementAsync}>异步加</button>&nbsp;
      </div>
    )
  }
}

  • 小节总结

新增文件:

(1). count_action.js:专门为Count组件服务创建action对象。

(2). constant.js:放置容易写错的type值。


4、Redux中开启异步action

Redux中,同步Action和异步Action的主要区别在于它们如何触发dispatch

同步Action: 当一个同步Action被创建时,它会立即被发送到store中,并等待store更新状态。如果有其他组件正在使用store,那么这些组件也会立即更新状态。因此,同步Action通常用于那些不需要等待的、简单的操作。

异步Action: 异步Action会在发出后继续执行其他操作,直到完成后再将结果发送到store中。这意味着,如果有其他组件正在使用store,那么它们可能不会立即看到更新的状态。因此,异步Action通常用于那些需要等待的操作。

  • 步骤1:编写一个异步的action的函数

普通的action返回的是一个Object的一般对象,而异步action返回的是一个函数,因为只有在函数里面才能进行异步操作。

文件:redux/count_action.js

// 该文件专门为Count组件生成action对象
import {INCREMENT,DECREMENT} from './constant'
// 一般action,返回的是一般对象
export const createIncrementAction = data => ({ type: INCREMENT,data})

export const createDecrementAction = data => ({ type: DECREMENT,data})
// 异步action,返回的是一个函数
export const createIncrementAsyncAction = (data,time) => {
    // 在返回的函数的参数是一个dispatch,用于我们处理完异步任务后分发action对象
    return (dispatch) => { 
      setTimeout(() => {
        dispatch(createIncrementAction(data))
      }, time);
    }
}
  • 步骤2:引入中间件来支持异步action

由于store分发action的时候,它只认普通对象,如果要接收一个函数就需要使用到一个中间件。

(1). 安装依赖redux-thunk

npm i redux-thunk

(2). 修改redux/store.js文件

// 引入createStore,专门用于创建redux中最为核心的store对象
import { createStore , applyMiddleware} from 'redux'
import countReducer from './count_reducer'

// 引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk'
export default createStore(countReducer,applyMiddleware(thunk))
  • 步骤3:在Count组件里面使用异步action
import React, { Component } from 'react'
import store from '../../redux/store'
// 引入actioncreator,专门用于创建action对象
import {  createIncrementAsyncAction} from '../../redux/count_action'
export default class Count extends Component {

 // ...

  incrementAsync = () => {
    // 异步加
    // 1、获取用户选择的值
    const { value } = this.selectNumber

    // 2、进行计算并更新状态值
    store.dispatch(createIncrementAsyncAction(value*1,500))
  }

  render() {
    return (
      <div>
        <h1>当前求和为:{store.getState()}</h1>
        <select ref={(c) => (this.selectNumber = c)}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        &nbsp;
        <button onClick={this.increment}>+</button>&nbsp;
        <button onClick={this.decrement}>-</button>&nbsp;
        <button onClick={this.incrementIfOdd}>当前求和为奇数为</button>&nbsp;
        <button onClick={this.incrementAsync}>异步加</button>&nbsp;
      </div>
    )
  }
}
  • 小节总结

    (1).明确:延迟的动作不想交给组件自身,想交给action

    (2).何时需要异步action:想要对状态进行操作,但是具体的数据靠异步任务返回

    (3).具体编码:

​ 1). npm i redux-thunk ,并配置在store

​ 2). 创建action的函数不再返回一般对象,而是一个函数,该函数中写异步任务

​ 3). 异步任务有结果后,分发一个同步的action去真正操作数据。

​ 4). 备注:异步任务action不是必须要写的,完全可以自己等待异步任务的结果完了,再去分发同步action

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle MRP补丁

参考文档&#xff1a; Oracle Database Oracle Database Patch Maintenance, Release 19c and Later Releases Introducing Monthly Recommended Patches (MRPs) and FAQ (Doc ID 2898740.1) - Sunsetting of 19c RURs and FAQ (Doc ID 2898381.1). Primary Note for D…

Sui基金会联合Tencent Cloud和Numen于5月24日在香港举办生态交流会

Sui生态工作坊及交流会将于5月24日在香港举行&#xff0c;本次活动旨在提升Web3产业对Sui生态的认识&#xff0c;并为生态中的开发者搭建交流的平台&#xff0c;促进团队之间的合作。在本次的交流会中&#xff0c;您还可以了解到Sui基金会对Web3生态发展愿景不遗余力的支持、Te…

深度学习课程:手写体识别示例代码和详细注释

Pytorch 的快速入门&#xff0c;参见 通过两个神经元的极简模型&#xff0c;清晰透视 Pytorch 工作原理。本文结合手写体识别项目&#xff0c;给出一个具体示例和直接关联代码的解释。 1. 代码 下面代码展示了完整的手写体识别的 Python 程序代码。代码中有少量注释。在本文后…

工业相机的Pixel Binning和Pixel Skipping

一般图像传感器的不同分辨率都对应着不同的帧率。如果想要提高帧率&#xff0c;就要考虑是否需要缩小视野。若不希望视野缩小&#xff0c;就需要减小分辨率&#xff08;resolution&#xff09;。常用的减少分辨率的两种采样方式是&#xff1a;Skipping和Binning。 什么是Binni…

【复盘】聊一下如何高效学习

对于大多数的人来说&#xff0c;从毕业之后其实大多数的可能就不会在认真学习专业和专业外的课程&#xff0c;但是对于程序员这个大群体来说&#xff0c;想要提高自己的技术&#xff0c;需要不断的提高自己的技术能力以及来提高薪资水平&#xff0c;那么有没有相关的高效学习的…

四种不同机器学习方法(线性回归模型,K近邻回归模型,决策树回归模型,随机森林回归模型)对光伏发电预测

1.数据集介绍&#xff08;可以看短期光伏发电量短期预测&#xff08;Python代码&#xff0c;基于LSTM模型&#xff09;_深度学习的奋斗者的博客-CSDN博客&#xff09; 两篇文章用的是同一个数据集&#xff0c;不同的的是本篇多了温度特征 这些是温度数据集中的列名&#xff1…

prettier 使用详细介绍

prettier 使用详细介绍 prettier是一个代码格式化工具&#xff0c;可以通过自定义规则来重新规范项目中的代码&#xff0c;去掉原始的代码风格&#xff0c;确保团队的代码使用统一相同的格式。 安装 npm i prettier -Dyarn add prettier --dev创建一个prettierrc.*配置文件&…

lambda、类

目录 1、lambda匿名函数 2、类 1、__init__() 2、继承 1、lambda匿名函数 语法 lambda arguments : expression 一个 lambda 函数&#xff0c;它把作为参数传入的数字加 10&#xff0c;然后打印结果 x lambda a : a 10print(x(5)) # 15 一个 lambda 函数&#x…

msys2 安装并使用 pacman 安装 dos2unix

问题描述 在 Windows 下使用 msys2 编译 Linux 环境的 代码时&#xff0c;经常遇到由于 【回车换行】造成某些配置文件&#xff0c;如 Kconfig 文件&#xff0c;无法正常解析导致编译失败的问题。 安装 msys2 安装 msys2 的方法很简单&#xff0c;只需要到官方 下载 http://w…

yum和repo详细解析

目录 一、rpm、yum、repo 二、repo文件详细解析 三、常用命令 四、更改epel.repo为清华源 一、rpm、yum、repo RPM RPM(Red-hat Package Manager)&#xff0c;是一个由红帽最早开发出来的包管理器&#xff0c;目前已经是大多数Linux发行的默认包管理器。RPM管理的包都是以…

Docker镜像与制作

Docker镜像与制作 Docker镜像是没有内核的&#xff0c;镜像在启动为容器后将直接使用宿主机的内核。 Docker镜像的制作分为了手动制作和自动制作&#xff08;基于DockerFile&#xff09; 1、制作nginx镜像 先准备一个目录&#xff0c; mkdir docker-images && cd d…

借助ChatGPT实现 PPT | 导图 | 短视频文案生成【AIGC】

文章目录 1、chatgpt 自动制作 PPT2、chatgpt 生成 Excel 公式3、chatgpt 生成思维导图4、chatgpt 快速生成短视频5、总结 1、chatgpt 自动制作 PPT 步骤如下&#xff1a; ①要求 chatgpt 生成 PPT 内容&#xff0c;以 markdown 格式输出&#xff1b; ②借助网站 mindshow.fun…

【C++】 哈希 (上)

文章目录 1. 哈希概念2. 哈希表直接定址法(常用)除留余数法(常用)解决哈希冲突方法1 ——闭散列 3. 闭散列的实现如何处理删除数据&#xff1f;定义数据结构insertlen为 _tables.size() 还是 _tables.capacity()&#xff1f;线性探测负载因子扩容 FindErase完整代码 1. 哈希概念…

SpringBoot项目打包部署到Nginx【无需配置Nginx】

0.前置知识 springboot打包的项目共分为jar和war两种类型 jar包 jar类型项目使用SpringBoot打包插件打包时&#xff0c;会在打成的jar中 内置一个tomcat 的jar 所以我们可以使用jdk直接运行&#xff0c;将功能代码放到其内置的tomcat中运行。 war包 在打包时需要将 内置的tom…

2023-05-20 技术与管理的照本宣科教条主义与从事实中成长-反思

摘要: 最近的两份工作遇到了极其严重的教条主义, 有多严重呢&#xff1f;几乎可以说人成了教条的教徒&#xff0c;做事就成了照本宣科的死板硬套, 简直匪夷所思。 结果就是对于现实问题简直就像是建立在空中楼阁之上&#xff0c;不但涉及到管理&#xff0c;更有技术上的。 教…

实训三:MLP配置(多链路捆绑的配置)

实训三&#xff1a;MLP配置 【实验目的】 掌握多链路捆绑的配置。验证配置。 【实验拓扑】 实验拓扑如图所示。 设备参数如表所示。 设备 接口 IP地址 子网掩码 默认网关 R1 Multilink 1 192.168.12.1 255.255.255.0 N/A R2 Multilink 1 192.168.12.2 255.255…

6年心得,从功能测试到测试开发,送给在测试路上一路走到黑的你

蓦然回首&#xff0c;软件测试风风雨雨的这就几年&#xff0c;起初每天的工作只是鼠标点点点&#xff0c;我还真不知道怎么办&#xff0c;闲的时候真的怀疑自己的存在价值&#xff0c;每天拿着7000的工资&#xff0c;飘荡在繁华的深圳&#xff0c;吃不饱也饿不死&#xff0c;未…

1.2 IAR 环境配置及编译

目录 一. 新建源码文件夹 二. 添加源文件到工程中 三. 编写一个简单的测试程序 四. 设置字体和行号 五. 工程配置 六. 编译链接工程 一. 新建源码文件夹 &#xff08;1&#xff09;在保存工作空间和工程的目录下&#xff0c;新建一个code文件夹&#xff0c;用于保存源码&…

斯坦福、Nautilus Chain等联合主办的 Hackathon 活动,现已接受报名

由 Stanford Blockchain Accelerator、Zebec Protocol、 Nautilus Chain、Rootz Lab 共同主办的黑客松活动&#xff0c;现已接受优秀项目提交参赛申请。 在加密行业发展早期&#xff0c;密码极客们就始终在对区块链世界基础设施&#xff0c;在发展方向的无限可能性进行探索。而…

计算机组成原理实验三-修改二进制文件的程序改变最终运行结果

实验资料&#xff1a; https://wwpv.lanzoue.com/b05drr8qh 密码:6wjx 计算机组成原理实验三 修改二进制文件的程序改变最终运行结果 复习实验二GCC选项&#xff1a;-E -S -c -o -v .\gcc.exe 1.c -> a.exe .\gcc.exe 1.c -o 21001302xx.exe&#xff08;1&#xff09;…