【Qt開發流程】之容器類1:介紹及常用容器類和使用Java風格迭代器進行遍歷

概述

Qt庫提供了一組通用的基于模板的容器類。這些類可用于存儲指定類型的項。例如,如果需要一個可調整大小的QString數組,可以使用QVector<QString>

這些容器類被設計成比STL容器更輕、更安全、更易于使用。如果不熟悉STL,或者更喜歡用Qt方式進行變成,那么就可以使用這些類來代替STL類

容器類是隱式共享的,它們是可重入的,并且它們針對速度、低內存消耗和最小的內聯代碼擴展進行了優化,從而產生更小的可執行文件。此外,當所有訪問它們的線程都將它們用作只讀容器時,它們是線程安全的。

要遍歷存儲在容器中的項,可以使用兩種類型的迭代器之一:java風格的迭代器stl風格的迭代器java風格的迭代器更容易使用并提供高級功能,而STL風格的迭代器稍微更有效,可以與QtSTL的泛型算法一起使用。

Qt還提供了foreach關鍵字,它可以很容易地遍歷容器中存儲的所有項。

Qt容器類介紹

Qt提供了以下順序容器:QList, QLinkedList, QVector, QStackQQueue。對于大多數應用程序,QList是最好的類型。雖然它是作為數組列表實現的,但它提供了非常快的前置和追加。如果需要一個鏈表,使用QLinkedList;如果想讓項目占用連續的內存位置,使用QVectorQStackQQueue是提供后進先出先進先出語義的方便類。

Qt還提供了這些關聯容器:QMapQMultiMapQHashQMultiHashQSet“Multi”容器方便地支持與單個鍵關聯的多個值。“哈希”容器通過使用哈希函數而不是對排序集進行二進制搜索來提供更快的查找。

作為特殊情況,QCacheqconsecuousscache類在有限的緩存存儲中提供了有效的對象哈希查找。

以下是常用容器類:
?

介紹
QList這是目前為止最常用的容器類。它存儲可以通過索引訪問的給定類型(T)的值列表。在內部,QList使用數組實現,確保基于索引的訪問非常快。
QLinkedList可以使用QList::append()和QList::prepend()在列表的兩端添加項,也可以使用QList::insert()在中間插入項。與任何其他容器類不同,QList經過了高度優化,可以在可執行文件中擴展到盡可能少的代碼。QStringList繼承自QList。這類似于QList,不同之處在于它使用迭代器而不是整數索引來訪問項。在大列表中插入時,它還提供了比QList更好的性能,并且具有更好的迭代器語義。(只要QLinkedList中的元素存在,指向該元素的迭代器就保持有效,而指向QList的迭代器在插入或刪除后就會失效。)
QVector這將給定類型的值數組存儲在內存中的相鄰位置。在vector的前面或中間插入可能會非常慢,因為它可能導致大量項必須在內存中移動一個位置。
QStack這是QVector的一個方便子類,提供“后進先出”(LIFO)語義。它為QVector中已經存在的函數添加了以下函數:push()、pop()和top()。
QQueue這是QList的一個方便子類,提供“先進先出”(FIFO)語義。它向QList中已經存在的函數添加了以下函數:enqueue()、dequeue()和head()。
QSet這提供了一個具有快速查找功能的單值數學集。
QMap<Key, T>它提供了一個字典(關聯數組),將Key類型的鍵映射到t類型的值。通常每個鍵都與單個值相關聯。QMap按Key順序存儲數據;如果順序不重要,QHash是一個更快的選擇。
QMultiMap<Key, T>這是QMap的一個方便的子類,它為多值映射提供了一個很好的接口,即一個鍵可以與多個值相關聯的映射。
QHash<Key, T>它具有與QMap幾乎相同的API,但提供了明顯更快的查找。QHash以任意順序存儲數據。
QMultiHash<Key, T>這是QHash的一個方便的子類,它為多值哈希提供了一個很好的接口。

?
容器是可以嵌套。例如,完全可以使用QMap<QString, QList<int>>,其中鍵類型是QString,值類型是QList<int>

容器在單獨的頭文件中定義,其名稱與容器相同(例如,<QLinkedList>)。為方便起見,在<QtContainerFwd>中向前聲明了容器。

存儲在各種容器中的值可以是任何可賦值的數據類型。要符合條件,類型必須提供默認構造函數、復制構造函數和賦值操作符。這涵蓋了可能想要存儲在容器中的大多數數據類型,包括基本類型,如intdouble,指針類型,以及Qt數據類型,如QString, QDateQTime,但它不包括QObject或任何QObject子類(QWidget, QDialog, QTimer等)。如果嘗試實例化QList<QWidget>,編譯器將報錯QWidget的復制構造函數和賦值操作符被禁用。如果希望將這些類型的對象存儲在容器中,請將它們存儲為指針,例如QList<QWidget *>

下面是一個滿足可賦值數據類型要求的自定義數據類型示例:

  class Employee{public:Employee() {}Employee(const Employee &other);Employee &operator=(const Employee &other);private:QString myName;QDate myDateOfBirth;};

?
如果沒有提供復制構造函數或賦值操作符,c++提供了執行逐個成員復制的默認實現。在上面的例子中,這就足夠了。此外,如果不提供任何構造函數,c++還提供一個默認構造函數,該構造函數使用默認構造函數初始化其成員。盡管它沒有提供任何顯式構造函數或賦值操作符,但下列數據類型可以存儲在容器中:

  struct Movie{int id;QString title;QDate releaseDate;};

?
有些容器對它們可以存儲的數據類型有額外的要求。例如,QMap<Key, T>Key類型必須提供操作符<()。這些特殊需求在類的詳細描述中都有文檔。在某些情況下,特定功能有特殊要求;這些是按功能描述的。如果不滿足要求,編譯器總是會發出一個錯誤。

Qt的容器提供了operator<<()operator>>(),因此它們可以很容易地使用QDataStream進行讀寫。這意味著存儲在容器中的數據類型還必須支持operator<<()operator>>()。提供這樣的支持是直截了當的;下面是我們如何為上面的Movie結構體做到這一點:

  QDataStream &operator<<(QDataStream &out, const Movie &movie){out << (quint32)movie.id << movie.title<< movie.releaseDate;return out;}QDataStream &operator>>(QDataStream &in, Movie &movie){quint32 id;QDate date;in >> id >> movie.title >> date;movie.id = (int)id;movie.releaseDate = date;return in;}

?
某些容器類函數的文檔引用默認構造的值;例如,QVector用默認構造的值自動初始化它的項,如果指定的鍵不在映射中,QMap::value()返回一個默認構造的值。對于大多數值類型,這僅僅意味著使用默認構造函數創建值(例如,QString的空字符串)。但是對于intdouble這樣的基本類型,以及指針類型,c++語言沒有指定任何初始化;在這種情況下,Qt的容器會自動將該值初始化為0

示例

以下是使用QListQMap進行介紹,其他幾個容器可以參考這兩個進行操作,因為他們的API很相似。
QList
QList是Qt中提供的一個容器類,它是一個動態數組,可以自動調整大小以容納新元素

  • append:在列表的末尾添加一個新元素。
QList<int> list;
list.append(1);
list.append(2);
list.append(3);
// list: {1, 2, 3}
  • prepend:在列表的開頭添加一個新元素。
QList<int> list;
list.prepend(1);
list.prepend(2);
list.prepend(3);
// list: {3, 2, 1}
  • insert:在列表的指定位置插入一個新元素。
QList<int> list;
list << 1 << 2 << 4;
list.insert(2, 3);
// list: {1, 2, 3, 4}
  • replace:用新元素替換列表中的一個元素。
QList<int> list;
list << 1 << 2 << 3;
list.replace(1, 4);
// list: {1, 4, 3}
  • removeAt:從列表中刪除指定索引處的元素。
QList<int> list;
list << 1 << 2 << 3;
list.removeAt(1);
// list: {1, 3}
  • swap:交換列表中兩個元素的位置。
QList<int> list;
list << 1 << 2 << 3;
list.swap(0, 2);
// list: {3, 2, 1}
  • contains:檢查列表中是否包含某個元素。
QList<int> list;
list << 1 << 2 << 3;
if (list.contains(2)) {qDebug() << "2 is in the list.";
}
  • count:返回列表中某個元素的數量。
QList<int> list;
list << 1 << 2 << 2 << 3 << 2;
int count = list.count(2); // count is 3
  • indexOf:返回列表中某個元素的第一個索引。
QList<int> list;
list << 1 << 2 << 2 << 3 << 2;
int index = list.indexOf(2); // index is 1
  • lastIndexOf:返回列表中某個元素的最后一個索引。
QList<int> list;
list << 1 << 2 << 2 << 3 << 2;
int index = list.lastIndexOf(2); // index is 4
  • empty:檢查列表是否為空。
QList<int> list;
if (list.empty()) {qDebug() << "The list is empty.";
}
  • size:返回列表的大小。
QList<int> list;
list << 1 << 2 << 3;
int size = list.size(); // size is 3
  • clear:刪除列表中的所有元素。
QList<int> list;
list << 1 << 2 << 3;
list.clear();
// list is now empty

對于只讀的訪問,一般使用at()函數,因為比"[ ]"操作符快很多。
QMap
QMap是Qt中提供的一個容器類,它是一個關聯數組,可以將鍵值對存儲在一起.

  • insert:在映射中插入一個鍵值對。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
map.insert("Charlie", 35);
// map: { "Alice": 30, "Bob": 25, "Charlie": 35 }
  • replace:用新值替換映射中的一個值。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
map.insert("Charlie", 35);
map.replace("Bob", 20);
// map: { "Alice": 30, "Bob": 20, "Charlie": 35 }
  • remove:從映射中刪除指定鍵的值。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
map.insert("Charlie", 35);
map.remove("Bob");
// map: { "Alice": 30, "Charlie": 35 }
  • swap:交換兩個映射的內容。
QMap<QString, int> map1, map2;
map1.insert("Bob", 25);
map1.insert("Alice", 30);
map2.insert("Charlie", 35);
map2.insert("Dave", 40);
map1.swap(map2);
// map1: { "Charlie": 35, "Dave": 40 }
// map2: { "Alice": 30, "Bob": 25 }
  • contains:檢查映射中是否包含指定鍵。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
if (map.contains("Bob")) {qDebug() << "Bob is in the map.";
}
  • count:返回映射中指定鍵的數量。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
map.insert("Charlie", 35);
int count = map.count("Bob"); // count is 1
  • value:返回映射中指定鍵的值,如果鍵不存在則返回默認值。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
int value = map.value("Charlie", 0); // value is 0
  • keys:返回映射中所有的鍵。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
QList<QString> keys = map.keys(); // keys: { "Bob", "Alice" }
  • values:返回映射中所有的值。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
QList<int> values = map.values(); // values: { 25, 30 }
  • empty:檢查映射是否為空。
QMap<QString, int> map;
if (map.empty()) {qDebug() << "The map is empty.";
}
  • size:返回映射中鍵值對的數量。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
int size = map.size(); // size is 2
  • clear:刪除映射中的所有鍵值對。
QMap<QString, int> map;
map.insert("Bob", 25);
map.insert("Alice", 30);
map.clear();
// map is now empty

遍歷容器

要遍歷存儲在容器中的項,可以使用兩種類型的迭代器之一:java風格的迭代器stl風格的迭代器java風格的迭代器更容易使用并提供高級功能,而STL風格的迭代器稍微更有效,可以與QtSTL的泛型算法一起使用。

Qt還提供了foreach關鍵字,它可以很容易地遍歷容器中存儲的所有項。
在這里插入圖片描述
在本文檔中,將集中討論QList和QMap。QLinkedList、QVector和QSet的迭代器類型與QList的迭代器具有完全相同的接口;類似地,QHash的迭代器類型與QMap的迭代器具有相同的接口。
與stl風格的迭代器(將在下面介紹)不同,java風格的迭代器指向項目之間,而不是直接指向項目。由于這個原因,它們要么指向容器的最開始(在第一個項目之前),要么指向容器的最末尾(在最后一個項目之后),要么指向兩個項目之間。下圖用紅色箭頭顯示了包含四個元素的列表的有效迭代器位置:
在這里插入圖片描述
下面,按順序遍歷QList中的所有元素,并將它們打印到控制臺:

  QList<QString> list;list << "A" << "B" << "C" << "D";QListIterator<QString> i(list);while (i.hasNext())qDebug() << i.next();

它的工作原理如下:將要迭代的QList傳遞給QListIterator構造函數。此時,迭代器位于列表中第一項的前面(在項“A”之前)。然后調用hasNext()來檢查迭代器后是否有項。如果有,則調用next()跳過該項。next()函數返回它跳過的項。對于QList,該項的類型為QString。
下面是如何在QList中向后迭代:

  QListIterator<QString> i(list);i.toBack();while (i.hasPrevious())qDebug() << i.previous();

代碼與向前迭代是對稱的,除了我們首先調用toBack()將迭代器移動到列表中的最后一項之后。
下圖說明了在迭代器上調用next()和previous()的效果:
在這里插入圖片描述
QListIterator常用API:

方法行為
toFront()將迭代器移動到列表的前面(在第一項之前)
toBack()將迭代器移動到列表的后面(在最后一項之后)
hasNext()如果迭代器不在列表的末尾,則返回true
next()返回下一項并將迭代器向前移動一個位置
peekNext()不移動迭代器返回下一項
hasPrevious()如果迭代器不在列表的前面,則返回true
previous()返回前一項并將迭代器向后移動一個位置
peekPrevious()不移動迭代器返回前一項

QListIterator不提供在迭代時從列表中插入或刪除項的函數。要做到這一點,必須使用QMutableListIterator
下面是一個使用QMutableListIteratorQList<int>中刪除所有奇數的例子:

  QMutableListIterator<int> i(list);while (i.hasNext()) {if (i.next() % 2 != 0)i.remove();}

循環中的next()調用每次都進行。它跳過列表中的下一項。remove()函數刪除了我們從列表中跳過的最后一項。調用remove()不會使迭代器失效,所以繼續使用它是安全的。這在向后迭代時同樣有效:

  QMutableListIterator<int> i(list);i.toBack();while (i.hasPrevious()) {if (i.previous() % 2 != 0)i.remove();}

就像remove()一樣,setValue()對我們跳過的最后一項進行操作。如果向前迭代,這是迭代器前面的項;如果向后迭代,這是迭代器后面的項。
next()函數返回對列表中項目的非const引用。對于簡單的操作,我們甚至不需要setValue():

  QMutableListIterator<int> i(list);while (i.hasNext())i.next() *= 2;

如上所述,QLinkedList、QVector和QSet的迭代器類具有與QList完全相同的API。現在我們將轉向QMapIterator,它有點不同,因為它對(鍵,值)對進行迭代。
與QListIterator一樣,QMapIterator提供toFront()、toBack()、hasNext()、next()、peekNext()、hasPrevious()、previous()和peekPrevious()。鍵和值組件是通過對next()、peekNext()、previous()或peekPrevious()返回的對象調用key()和value()來提取的。
下面的例子刪除所有以"City"結尾的(capital, country)對:

  QMap<QString, QString> map;map.insert("Paris", "France");map.insert("Guatemala City", "Guatemala");map.insert("Mexico City", "Mexico");map.insert("Moscow", "Russia");...QMutableMapIterator<QString, QString> i(map);while (i.hasNext()) {if (i.next().key().endsWith("City"))i.remove();}

QMapIterator還提供了一個key()和一個value()函數,它們直接對迭代器進行操作,并返回迭代器跳到上面的最后一項的鍵和值。例如,下面的代碼將QMap的內容復制到QHash中:

  QMap<int, QWidget *> map;QHash<int, QWidget *> hash;QMapIterator<int, QWidget *> i(map);while (i.hasNext()) {i.next();hash.insert(i.key(), i.value());}

如果要遍歷具有相同值的所有項,可以使用findNext()或findPrevious()。下面是一個例子,刪除所有具有特定值的項:

  QMutableMapIterator<int, QWidget *> i(map);while (i.findNext(widget))i.remove();

結論

想改變物質生活,后來發現,改變心態更容易

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/212567.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/212567.shtml
英文地址,請注明出處:http://en.pswp.cn/news/212567.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

低多邊形3D建模石頭材質紋理貼圖

在線工具推薦&#xff1a; 3D數字孿生場景編輯器 - GLTF/GLB材質紋理編輯器 - 3D模型在線轉換 - Three.js AI自動紋理開發包 - YOLO 虛幻合成數據生成器 - 三維模型預覽圖生成器 - 3D模型語義搜索引擎 當談到游戲角色的3D模型風格時&#xff0c;有幾種不同的風格&#xf…

云計算在計算機領域的應用與發展

云計算在計算機領域的應用與發展 一、引言 隨著科技的不斷發展&#xff0c;計算機領域已經成為當今社會最為活躍和創新的領域之一。云計算作為一種新興的計算模式&#xff0c;已經在計算機領域中得到了廣泛的應用&#xff0c;并且正在不斷地推動著計算機領域的發展。本文將探…

Ultimate VFX

Ultimate VFX 構建套件:

【利用二手車數據進行可視化分析】

利用二手車數據進行可視化分析 查看原始數據去除重復數據需求分析1.統計全國總共有多少量二手車&#xff0c;用KPI圖進行展示2.統計安徽總共有多少量二手車&#xff0c;用KPI圖進行展示3.統計合肥總共有多少量二手車&#xff0c;用KPI圖進行展示4.取最貴的10輛二手車信息&#…

web,Apache簡述

一.HTTP請求訪問的完整過程 1.建立連接 2.接收請求 3.處理請求 4.訪問資源 服務器獲取請求報文中請求的資源web服務器&#xff0c;即存放了web資源的服務器&#xff0c;負責向請求者提供對方請求的靜態資源&#xff0c;或動態運行后生成的資源 靜態資源&#xff1a;不需要…

C語言 內聯函數 + 遞歸函數

函數分類 內聯函數 1&#xff09;內聯函數在編譯時將函數的代碼直接插入到調用它的地方&#xff0c;而不是通過函數調用的方式執行&#xff0c;從而減少了函數調用的開銷&#xff0c;提高了代碼的執行速度 2&#xff09;使用 inline 關鍵字來聲明 3&#xff09;將函數聲明為內聯…

小目標檢測模型設計的一點思考

1. 小目標的特性 目標之間的交疊概率比較低&#xff0c;即使有交疊&#xff0c;其IoU多數情況下也是比較小的 AI-TOD Tiny Person Dateset 小目標自身的紋理顯著度有強弱區別&#xff0c;但是總體來說紋理特征都較弱&#xff0c;很多時候需要借助一定的圖像上下文來幫助確認 …

Java解決島嶼周長問題

Java解決島嶼周長問題 01 題目 給定一個 row x col 的二維網格地圖 grid &#xff0c;其中&#xff1a;grid[i][j] 1 表示陸地&#xff0c; grid[i][j] 0 表示水域。 網格中的格子 水平和垂直 方向相連&#xff08;對角線方向不相連&#xff09;。整個網格被水完全包圍&am…

ssm校園論壇管理系統項目分享

校園論壇管理系統是基于java編程語言&#xff0c;mysql數據庫&#xff0c;ssm框架和idea工具開發&#xff0c;本系統主要分為學生用戶&#xff0c;管理員兩個角色&#xff0c;其中用戶可以注冊登陸系統&#xff0c;在線發帖&#xff0c;查看欄目帖子&#xff0c;回復帖子&#…

某音上很火的圣誕樹分享

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站。 效果截圖&#xff08;這里不給動態了&#xff0c;某音到處都是了&#xff09;&#xff1a; 源代碼&#xff1a; <script src"…

Spring Boot 3 集成 MyBatis詳解

MyBatis是一款開源的持久層框架&#xff0c;它極大地簡化了與數據庫的交互流程。與類似Hibernate的ORM框架不同&#xff0c;MyBatis更具靈活性&#xff0c;允許開發者直接使用SQL語句與數據庫進行交互。Spring Boot和MyBatis分別是兩個功能強大的框架&#xff0c;它們的協同使用…

Linux shell編程學習筆記34:eval 命令

0 前言 在JavaScript語言中&#xff0c;有一個很特別的函數eval&#xff0c;eval函數可以將字符串當做 JavaScript 代碼執行&#xff0c;返回表達式或值。 在Linux Shell 中也提供了內建命令eval&#xff0c;它是否具有JavaScript語言中eval函數的功能呢&#xff1f; 1 eval命…

GPIO的使用--USART串口通信--傳感器控制數據

目錄 一、串口通信 1、概念 2、原理圖 3、使用步驟 &#xff08;1&#xff09;尋找串口位置 &#xff08;2&#xff09;確定引腳編號 &#xff08;3&#xff09;編寫代碼 4、實驗結果 實驗代碼 main.c usart.c usart.h 一、串口通信 1、概念 串行接口是一種可以將…

DiffiT

本文首發于AIWalker&#xff0c;歡迎關注。 https://arxiv.org/abs/2312.02139 https://github.com/NVlabs/DiffiT 擴散模型以其強大的表達能力和高樣本質量在許多領域得到了新的應用。對于樣本生成&#xff0c;這些模型依賴于通過迭代去噪生成圖像的去噪神經網絡。然而&#x…

SAP UI5 walkthrough step8 Translatable Texts

在這個章節&#xff0c;我們會將一些文本常量獨立出一個資源文件 這樣的話&#xff0c;可以方便這些文本常量被翻譯成任意的語言 這種國際化的操作&#xff0c;我們一般命名為i18n 新建一個文件i18n.properties webapp/i18n/i18n.properties (New) showHelloButtonTextSay …

vue3項目實現文檔 JSON 格式和 Excel 表格的在線預覽,(智能搜索,未驗證)

若要實現文檔 JSON 格式和 Excel 表格的在線預覽&#xff0c;你可以使用第三方庫來實現。對于文檔 JSON 格式&#xff0c;你可以使用 vue-json-pretty 庫來展示美觀的 JSON 數據&#xff1b;對于 Excel 表格&#xff0c;你可以使用 vue-excel-viewer 庫來完成在線預覽。下面是一…

Java、Spring Boot和事務管理

引言 在現代應用程序開發中&#xff0c;確保數據的一致性和可靠性是至關重要的。Java作為一種強大的編程語言&#xff0c;通過其廣泛的生態系統和強大的庫支持&#xff0c;為開發人員提供了構建高性能應用程序的豐富工具。Spring Boot是一個基于Spring框架的項目&#xff0c;它…

圖像的均方差和信噪比計算

圖像的均方差和信噪比計算 一、均方差1、公式2、代碼 二、信噪比1、公式2、代碼 圖像的均方差和信噪比公式及代碼&#xff0c;代碼基于opencv和C實現。 一、均方差 均方誤差&#xff0c;英文簡稱&#xff1a;MSE&#xff0c;英文全稱&#xff1a;“Mean Square Error”。 衡量…

接口測試-Jmeter使用

一、線程組 1.1 作用 線程組就是控制Jmeter用于執行測試的一組用戶 1.2 位置 右鍵點擊‘測試計劃’-->添加-->線程(用戶)-->線程組 1.3 特點 模擬多人操作線程組可以添加多個&#xff0c;多個線程組可以并行或者串行取樣器(請求)和邏輯控制器必須依賴線程組才能…

「Verilog學習筆記」多bit MUX同步器

專欄前言 本專欄的內容主要是記錄本人學習Verilog過程中的一些知識點&#xff0c;刷題網站用的是牛客網 輸入數據暫存在data_reg中&#xff0c;使能信號data_en用打兩拍的方式跨時鐘域傳輸到時鐘域B&#xff0c;最后data_out根據使能信號更新數據。data_en信號在A時鐘域用一個D…