关于深拷贝浅拷贝的相关问题

news2024/9/22 19:20:04

深拷贝和浅拷贝区别了解吗?什么是引用拷贝?写一下实现深拷贝或者浅拷贝的具体代码

深拷贝和浅拷贝的区别

深拷贝和浅拷贝是两种复制对象的方法,区别在于是否复制了对象内部的数据。

浅拷贝只复制了对象的第一层属性,深拷贝可以对对象的属性进行递归复制。

深拷贝是创建一个新的对象并且递归复制原对象内部属性,新对象和原对象完全独立,修改其中任何一个不会对另外一个对象造成影响。

浅拷贝是将原对象的引用赋值给新对象,新旧对象共享同一块内存,其中一个对象修改了内存中的数据,另外一个对象也会受到影响。

引用拷贝

引用拷贝是指将一个对象的引用直接赋值给另一个变量,使得两个变量指向同一个对象。这样,在修改其中一个变量所指向的对象时,另一个变量也会随之改变。

引用拷贝通常发生在传递参数、返回值等场景中。例如,在 Java 中,如果将一个对象作为参数传递给方法,实际上是将该对象的引用传递给了方法,而不是对象本身的拷贝。

需要注意的是,引用拷贝并非真正意义上的拷贝,而是共享同一份数据。因此,对于引用拷贝的对象,在修改其内部数据时需要注意是否会影响到其他使用该对象的地方。

总结

浅拷贝:创建一个新对象,保存原始对象属性值精准拷贝。如果属性是基本类型,拷贝的是基本类型的值,如果属性是引用类型,拷贝的是内存地址,并不会占用新的内存,这种情况下如果其中一个对象改变了这个地址,会影响到另一个对象。浅拷贝只复制指向某个对象的指针,而不复制对象本身。新旧对象共享同一块内存。

深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,增加了内存,且修改新对象不会影响原对象。新对象与原对象不共享内存。
引用拷贝是将一个对象的引用赋值给另一个变量,使得两个变量指向同一个对象。

浅拷贝仅复制对象的引用,而深拷贝复制对象本身及其引用的对象。在需要隔离对象以避免相互影响的场景下,深拷贝是更合适的选择。

实现深拷贝的方法

Object.assign()

当且仅当对象的属性值为简单类型(string,number),通过Object.assign({},srcobj);得到的新对象为深拷贝;

关于object.assign()
Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象,Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

var obj={
  a:1,
	b:2
}
var obj1=Object.assign({},obj);
obj1.a=6;
console.log("obj.a",obj.a)
console.log("obj1.a",obj1.a)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
新对象obj1的a属性值为6,旧对象obj的a的属性值为1,旧的对象没有因为新对象的改变而受到影响,所以上面的代码实现的是深拷贝。

JSON.parse()和JSON.stringify()

使用JSON.stringify和JSON.parse实现深拷贝:JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象;

let arr1=[1, [1, 2], 3, 4];
let arr2 = JSON.parse(JSON.stringify(arr1));
arr2[1][0] = 2;
console.log(arr1);//[ 1, [ 1, 2 ], 3, 4 ]
console.log(arr2);//[ 1, [ 2, 2 ], 3, 4 ]

修改新对象不影响旧对象,不共享同一块内存,是深拷贝。
缺点是不能处理函数和正则

函数库lodash的_.cloneDeep方法

关于运行js脚本怎么引入lodash,我先新建一个文件夹,文件夹内新建demo1.js,之后再demo1.js里面写如下代码,之后命令运行脚本 node demo1.js得出结果,深拷贝,改变新对象的对象属性,原对象的对象属性不受影响。

var _ = require('lodash');
var obj1 = {
  a: 1,
  b: 2,
  c: {
    d: 3
  }
}
var obj2 = _.cloneDeep(obj1);
obj2.a=6;
console.log("obj1.a:"+obj1.a+"obj2.a:"+obj2.a)
obj2.c.d=9
console.log(obj2.c.d)
console.log(obj1.c.d)

在这里插入图片描述

手写递归实现

解决循环引用的问题

function deepClone(obj, hash=new WeakMap()) {
  if(obj == null) return obj; // 不操作
  if(obj instanceof Date) return new Date(obj);
  if(obj instanceof RegExp) return new RegExp(obj);
  // 普通值/函数不需要深拷贝
  if(typeof obj !== "object") return obj;
  // 是对象的话要进行深拷贝
  if(hash.get(obj)) return hash.get(obj);
  let cloneObj = new obj.constructor();
  // 找到的是所属类原型上的constructor,而原型上的constructor指向的是当前类本身
  hash.set(obj. cloneObj);
  for(let key in obj) {
    if(obj.hasOwnProperty(key)) {
      cloneObj[key] = deepClone(obj[key], hash)
    }
  }
  return cloneObj;
}

实现浅拷贝的方法

Object.assign()

如果对象的属性值为对象或其他引用类型,通过Object.assign({},srcobj);得到的新对象为浅拷贝;

let demo = {'name': 'lilei', 'grade': {'math':"80", 'English':"100"}};
let demo1 = Object.assign({}, demo);
demo1.name="zhangsan";
demo1.grade.math="100";
console.log('demo.name', demo.name,'demo.grade.math',demo.grade.math);		
console.log('demo1', demo1);	

运行结果

demo.name lilei demo.grade.math 100
demo1 { name: ‘zhangsan’, grade: { math: ‘100’, English: ‘100’ } }

原对象demo的name是基本类型(string),所以这里是深拷贝,新对象的name修改为张三,原对象demo的name仍然是lilei,不受影响。
但是关于原始对象的grade属性是一个对象,使用Object.assign()方法修改对象的对象属性是浅拷贝,数据共享一块内存,修改新对象demo1的grade对象属性,原对象demo的grade对象属性也会随之改变。

for in

function simpleCopy(obj1) {
var obj2 = Array.isArray(obj1) ? [] : {};
for (let i in obj1) {
  obj2[i] = obj1[i];
}
  return obj2;
}
var obj1 = {
  a: 1,
  b: 2,
  c: {
    d: 3
  }
}
var obj2 = simpleCopy(obj1);
obj2.a = 3;
obj2.c.d = 4;
console.log(obj1.a); // 1
console.log(obj2.a); // 3
console.log(obj1.c.d); // 4
console.log(obj2.c.d); // 4

使用for-in将原对象或者原数组的值赋值给新的对象或者新的数组,修改原对象的简单类型(string)属性,新对象不受影响,obj2.a = 3;obj1.a=1;修改原对象的对象属性比如修改c的属性值,新对象也会随之改变。obj1.c.d=4;obj2.c.d=4;

函数库lodash的_.clone方法

var _ = require('lodash');
var obj2 = _.clone(obj1);

展开运算符

同object.assign()功能相同

var obj1 = {
  a: 1,
  b: 2,
  c: {
    d: 3
  }
}
let obj2 = {...obj1}
obj2.a = 3;
obj2.c.d = 4;
console.log(obj1.a); // 1
console.log(obj2.a); // 3
console.log(obj1.c.d); // 4
console.log(obj2.c.d); // 4

代码运行结果和Object.assign()运行结果相同,如果对象的属性是基本类型,比如string,number,复制对象的时候是深拷贝,修改新对象的属性,旧对象不受影响。
如果对象的属性是对象或者引用类型,那么复制对象是浅拷贝,新旧对象共享一块内存,修改新对象,旧对象对应的属性也会随之改变。
深拷贝和浅拷贝区别了解吗?什么是引用拷贝?写一下实现深拷贝或者浅拷贝的具体代码

深拷贝和浅拷贝的区别

深拷贝和浅拷贝是两种复制对象的方法,区别在于是否复制了对象内部的数据。

浅拷贝只复制了对象的第一层属性,深拷贝可以对对象的属性进行递归复制。

深拷贝是创建一个新的对象并且递归复制原对象内部属性,新对象和原对象完全独立,修改其中任何一个不会对另外一个对象造成影响。

浅拷贝是将原对象的引用赋值给新对象,新旧对象共享同一块内存,其中一个对象修改了内存中的数据,另外一个对象也会受到影响。

引用拷贝

引用拷贝是指将一个对象的引用直接赋值给另一个变量,使得两个变量指向同一个对象。这样,在修改其中一个变量所指向的对象时,另一个变量也会随之改变。

引用拷贝通常发生在传递参数、返回值等场景中。例如,在 Java 中,如果将一个对象作为参数传递给方法,实际上是将该对象的引用传递给了方法,而不是对象本身的拷贝。

需要注意的是,引用拷贝并非真正意义上的拷贝,而是共享同一份数据。因此,对于引用拷贝的对象,在修改其内部数据时需要注意是否会影响到其他使用该对象的地方。

总结

浅拷贝:创建一个新对象,保存原始对象属性值精准拷贝。如果属性是基本类型,拷贝的是基本类型的值,如果属性是引用类型,拷贝的是内存地址,并不会占用新的内存,这种情况下如果其中一个对象改变了这个地址,会影响到另一个对象。浅拷贝只复制指向某个对象的指针,而不复制对象本身。新旧对象共享同一块内存。

深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,增加了内存,且修改新对象不会影响原对象。新对象与原对象不共享内存。
引用拷贝是将一个对象的引用赋值给另一个变量,使得两个变量指向同一个对象。

浅拷贝仅复制对象的引用,而深拷贝复制对象本身及其引用的对象。在需要隔离对象以避免相互影响的场景下,深拷贝是更合适的选择。

实现深拷贝的方法

Object.assign()

当且仅当对象的属性值为简单类型(string,number),通过Object.assign({},srcobj);得到的新对象为深拷贝;

关于object.assign()
Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象,Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

var obj={
  a:1,
	b:2
}
var obj1=Object.assign({},obj);
obj1.a=6;
console.log("obj.a",obj.a)
console.log("obj1.a",obj1.a)

新对象obj1的a属性值为6,旧对象obj的a的属性值为1,旧的对象没有因为新对象的改变而受到影响,所以上面的代码实现的是深拷贝。

JSON.parse()和JSON.stringify()

使用JSON.stringify和JSON.parse实现深拷贝:JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象;

let arr1=[1, [1, 2], 3, 4];
let arr2 = JSON.parse(JSON.stringify(arr1));
arr2[1][0] = 2;
console.log(arr1);//[ 1, [ 1, 2 ], 3, 4 ]
console.log(arr2);//[ 1, [ 2, 2 ], 3, 4 ]

修改新对象不影响旧对象,不共享同一块内存,是深拷贝。
缺点是不能处理函数和正则

函数库lodash的_.cloneDeep方法

关于运行js脚本怎么引入lodash,我先新建一个文件夹,文件夹内新建demo1.js,之后再demo1.js里面写如下代码,之后命令运行脚本 node demo1.js得出结果,深拷贝,改变新对象的对象属性,原对象的对象属性不受影响。

var _ = require('lodash');
var obj1 = {
  a: 1,
  b: 2,
  c: {
    d: 3
  }
}
var obj2 = _.cloneDeep(obj1);
obj2.a=6;
console.log("obj1.a:"+obj1.a+"obj2.a:"+obj2.a)
obj2.c.d=9
console.log(obj2.c.d)
console.log(obj1.c.d)

在这里插入图片描述

手写递归实现

解决循环引用的问题

function deepClone(obj, hash=new WeakMap()) {
  if(obj == null) return obj; // 不操作
  if(obj instanceof Date) return new Date(obj);
  if(obj instanceof RegExp) return new RegExp(obj);
  // 普通值/函数不需要深拷贝
  if(typeof obj !== "object") return obj;
  // 是对象的话要进行深拷贝
  if(hash.get(obj)) return hash.get(obj);
  let cloneObj = new obj.constructor();
  // 找到的是所属类原型上的constructor,而原型上的constructor指向的是当前类本身
  hash.set(obj. cloneObj);
  for(let key in obj) {
    if(obj.hasOwnProperty(key)) {
      cloneObj[key] = deepClone(obj[key], hash)
    }
  }
  return cloneObj;
}

测试循环引用

let objA = {name: "Alice"};
let objB = {name: "Bob"};
objA.friend = objB;
objB.friend = objA;

let clonedObj = deepClone(objA);
console.log(clonedObj);

在这里插入图片描述

实现浅拷贝的方法

Object.assign()

如果对象的属性值为对象或其他引用类型,通过Object.assign({},srcobj);得到的新对象为浅拷贝;

let demo = {'name': 'lilei', 'grade': {'math':"80", 'English':"100"}};
let demo1 = Object.assign({}, demo);
demo1.name="zhangsan";
demo1.grade.math="100";
console.log('demo.name', demo.name,'demo.grade.math',demo.grade.math);		
console.log('demo1', demo1);	

运行结果

demo.name lilei demo.grade.math 100
demo1 { name: ‘zhangsan’, grade: { math: ‘100’, English: ‘100’ } }

原对象demo的name是基本类型(string),所以这里是深拷贝,新对象的name修改为张三,原对象demo的name仍然是lilei,不受影响。
但是关于原始对象的grade属性是一个对象,使用Object.assign()方法修改对象的对象属性是浅拷贝,数据共享一块内存,修改新对象demo1的grade对象属性,原对象demo的grade对象属性也会随之改变。

for in

function simpleCopy(obj1) {
var obj2 = Array.isArray(obj1) ? [] : {};
for (let i in obj1) {
  obj2[i] = obj1[i];
}
  return obj2;
}
var obj1 = {
  a: 1,
  b: 2,
  c: {
    d: 3
  }
}
var obj2 = simpleCopy(obj1);
obj2.a = 3;
obj2.c.d = 4;
console.log(obj1.a); // 1
console.log(obj2.a); // 3
console.log(obj1.c.d); // 4
console.log(obj2.c.d); // 4

使用for-in将原对象或者原数组的值赋值给新的对象或者新的数组,修改原对象的简单类型(string)属性,新对象不受影响,obj2.a = 3;obj1.a=1;修改原对象的对象属性比如修改c的属性值,新对象也会随之改变。obj1.c.d=4;obj2.c.d=4;

函数库lodash的_.clone方法

var _ = require('lodash');
var obj2 = _.clone(obj1);

展开运算符

同object.assign()功能相同

var obj1 = {
  a: 1,
  b: 2,
  c: {
    d: 3
  }
}
let obj2 = {...obj1}
obj2.a = 3;
obj2.c.d = 4;
console.log(obj1.a); // 1
console.log(obj2.a); // 3
console.log(obj1.c.d); // 4
console.log(obj2.c.d); // 4

代码运行结果和Object.assign()运行结果相同,如果对象的属性是基本类型,比如string,number,复制对象的时候是深拷贝,修改新对象的属性,旧对象不受影响。
如果对象的属性是对象或者引用类型,那么复制对象是浅拷贝,新旧对象共享一块内存,修改新对象,旧对象对应的属性也会随之改变。

concat和slice方法

举例说明,假设我们有一个嵌套数组对象 arr1

let arr1 = [1, [2, 3], {a: 4}];

现在我们来使用 concat() 和 slice() 方法对 arr1 进行浅拷贝:

let arr2Concat = arr1.concat(); // 使用 concat() 方法进行浅拷贝
let arr2Slice = arr1.slice();   // 使用 slice() 方法进行浅拷贝

在这种情况下,无论使用 concat() 还是 slice() 方法创建的新数组,嵌套数组 [2, 3] 和对象 {a: 4} 都只是复制了它们的引用。这意味着如果在 arr2Concat 或 arr2Slice 中修改了嵌套数组或对象,那么原始数组 arr1 中对应的元素也会受到影响。

arr2Concat[1][0] = 100;    // 修改 arr2Concat 中嵌套数组的元素
arr2Concat[2].a = 400;     // 修改 arr2Concat 中对象的属性

console.log(arr1);         // 输出:[1, [100, 3], {a: 400}]
console.log(arr2Concat);   // 输出:[1, [100, 3], {a: 400}]
console.log(arr2Slice);    // 输出:[1, [2, 3], {a: 4}]

无论是 arr2Concat 还是 arr2Slice 都只是进行了浅拷贝,所以修改新数组中的嵌套数组或对象会影响原始数组中的相应元素。

Array.prototype.concat()

let arr2 = arr1.concat() // 返回新数组,但当数组中嵌套数组对象时为浅拷贝

Array.prototype.slice()

let arr2 = arr1.slice() // 返回新数组,但当数组中嵌套数组对象时为浅拷贝

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

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

相关文章

【Linux】线程——生产者消费者模型、基于阻塞队列的生产消费者模型、基于环形队列的生产消费者模型、POSIX信号量的概念和使用

文章目录 Linux线程6. 生产消费者模型6.1 基于阻塞队列的生产消费者模型6.1.1 阻塞队列模型实现 6.2 基于环形队列的生产消费者模型6.2.1 POSIX信号量的概念6.2.2 POSIX信号量的使用6.2.3 环形队列模型实现 Linux线程 6. 生产消费者模型 生产消费者模型的概念 生产者消费者模…

1-2、truffle与webjs亲密接触(truffle智能合约项目实战)

1-2、truffle与webjs亲密接触(truffle智能合约项目实战) 5,web3调用智能合约6,Ganache 5,web3调用智能合约 在前面已经完成简单的合约编写 使用web3调用此函数 Web端的代码使用web3进行智能合约的访问 首先在cmd以…

Burp安全扫描Web应用

一、浏览器设置代理 如下图所示,点击火狐浏览器的“扩展和主题”,搜索“代理”。 如下图所示,选择搜索到的第一个代理(选择任何一个都可以)。 如上图所示,第一个点击后,进入如下页面&#xff0…

ubuntu22.04 配置grpc(优化官方教程)

优化了官方教程,2024.7.17顺利打通。 一:添加环境变量 打开root文件夹下的 .bashrc 文件 编辑文件:滚动到文件的底部,然后添加以下行: export MY_INSTALL_DIR$HOME/.local mkdir -p "$MY_INSTALL_DIR" exp…

web安全之跨站脚本攻击xss

定义: 后果 比如黑客可以通过恶意代码,拿到用户的cookie就可以去登陆了 分类 存储型 攻击者把恶意脚本存储在目标网站的数据库中(没有过滤直接保存),当用户访问这个页面时,恶意脚本会从数据库中被读取并在用户浏览器中执行。比如在那些允许用户评论的…

BiLSTM 实现股票多变量时间序列预测(PyTorch版)

前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对…

首个WebAgent在线评测框架和流程数据管理平台来了,GPT-4、Qwen登顶闭源和开源榜首!

在当今科技迅速发展的时代,大型语言模型(Large Language Model,LLM)正以前所未有的速度改变着我们与数字世界的互动方式。基于LLM的智能代理(LLM Agent),从简单的信息搜索到复杂的网页操作&…

C1W4.Assignment.Naive Machine Translation and LSH

理论课:C1W4.Machine Translation and Document Search 文章目录 1. The word embeddings data for English and French words1.1The dataThe subset of dataLoad two dictionaries 1.2 Generate embedding and transform matricesExercise 1: Translating English…

防溺水预警系统引领水域安全新篇章

一、系统概述 随着人们对水域活动的需求增加,溺水事故频发,给人们的生命安全带来了严重威胁。然而,如今,一项创新科技正在以强大的功能和无限的潜力引领着水域安全的新篇章。智能防溺水预警系统,作为一种集成了智能感知…

CentOS 7 安装MySQL 5.7.30

CentOS 7 安装MySQL卸载(离线安装) 安装配置MySQL之前先查询是否存在,如存在先卸载再安装 rpm -qa|grep -i mysql rpm -qa|grep -i mariadb rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64如下命令找到直接 rm -rf 删除(删除…

定制开发AI智能名片商城微信小程序在私域流量池构建中的应用与策略

摘要 在数字经济蓬勃发展的今天,私域流量已成为企业竞争的新战场。定制开发AI智能名片商城微信小程序,作为私域流量池构建的创新工具,正以其独特的优势助力企业实现用户资源的深度挖掘与高效转化。本文深入探讨了定制开发AI智能名片商城微信…

修改了mybatis的xml中的sql不重启服务器如何动态加载更新

目录 一、背景 二、注意 三、代码 四、使用示例 五、其他参考博客 一、背景 开发一个报表功能,好几百行sql,每次修改完想自测下都要重启服务器,启动一次服务器就要3分钟,重启10次就要半小时,耗不起时间呀。于是在…

获取欧洲时报中国板块前新闻数据-scrapy

这里写目录标题 1.创建项目文件二.爬虫文件编写三.管道存储四.settings文件 1.创建项目文件 创建scrapy项目的命令&#xff1a;scrapy startproject <项目名字> 示例&#xff1a; scrapy startproject myspiderscrapy genspider <爬虫名字> <允许爬取的域名>…

tinymce富文本支持word内容同时粘贴文字图片上传 vue2

效果图 先放文件 文件自取tinymce: tinymce富文本简单配置及word内容粘贴图片上传 封装tinymce 文件自取&#xff1a;tinymce: tinymce富文本简单配置及word内容粘贴图片上传 页面引用组件 <TinymceSimplify refTinymceSimplify v-model"knowledgeBlockItem.content…

vue使用audio 音频实现播放与关闭(可用于收到消息给提示音效)

这次项目中因为对接了即时通讯 IM&#xff0c;有个需求就是收到消息需要有个提示音效&#xff0c;所以这里就想到了用HTML5 提供的Audio 标签&#xff0c;用起来也是很方便&#xff0c;首先让产品给你个提示音效&#xff0c;然后你放在项目中&#xff0c;使用Audio 标签&#x…

HardeningMeter:一款针对二进制文件和系统安全强度的开源工具

关于HardeningMeter HardeningMeter是一款针对二进制文件和系统安全强度的开源工具&#xff0c;该工具基于纯Python开发&#xff0c;经过了开发人员的精心设计&#xff0c;可以帮助广大研究人员全面评估二进制文件和系统的安全强化程度。 功能特性 其强大的功能包括全面检查各…

【BUG】已解决:WslRegisterDistribution failed with error: 0x800701bc

已解决&#xff1a;WslRegisterDistribution failed with error: 0x800701bc 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武…

Ubuntu22.04安装CUDA+CUDNN+Conda+PyTorch

步骤&#xff1a; 1、安装显卡驱动&#xff1b; 2、安装CUDA&#xff1b; 3、安装CUDNN&#xff1b; 4、安装Conda&#xff1b; 5、安装Pytorch。 一、系统和硬件信息 1、Ubuntu 22.04 2、显卡&#xff1a;4060Ti 二、安装显卡驱动 &#xff08;已经安装的可以跳过&a…

通过SchedulingConfigurer 接口完成动态定时任务

通过SchedulingConfigurer 接口完成动态定时任务 一.背景 在Spring中&#xff0c;除了使用Scheduled注解外&#xff0c;还可以通过实现SchedulingConfigurer接口来创建定时任务。它们之间的主要区别在于灵活性和动态性。Scheduled注解适用于固定周期的任务&#xff0c;一旦任…

【STM32 HAL库】I2S的使用

使用CubeIDE实现I2S发数据 1、配置I2S 我们的有效数据是32位的&#xff0c;使用飞利浦格式。 2、配置DMA **这里需要注意&#xff1a;**i2s的DR寄存器是16位的&#xff0c;如果需要发送32位的数据&#xff0c;是需要写两次DR寄存器的&#xff0c;所以DMA的外设数据宽度设置16…