C++編譯期計算:常量表達式(constexpr)全解析

在C++性能優化領域,"將計算盡可能轉移到編譯期"是一條黃金法則。編譯期計算(Compile-Time Computation)能顯著減少程序運行時的開銷,提升執行效率,同時還能在編譯階段暴露潛在錯誤。C++11引入的constexpr關鍵字及其后續演進(C++14/17/20),為開發者提供了一套完整的編譯期計算工具鏈,徹底改變了傳統模板元編程的復雜局面。

本文將從constexpr的基礎語法出發,系統講解其在變量、函數、類中的應用,深入分析編譯期計算的實現原理與性能優勢,并通過實戰案例展示如何利用constexpr解決實際開發中的性能瓶頸,幫助開發者充分發揮編譯期計算的潛力。

一、編譯期計算與constexpr概述

1.1 什么是編譯期計算?

編譯期計算指在程序編譯階段完成的計算,其結果直接嵌入到生成的二進制代碼中,而非在程序運行時動態計算。例如,3 + 5在編譯期即可計算為8,無需在運行時執行加法指令。

傳統C++中,編譯期計算依賴:

  • 字面量常量(如423.14
  • enum枚舉常量
  • 模板元編程(TMP)的編譯期遞歸

但這些方式存在明顯局限:模板元編程語法晦澀,枚舉常量功能有限,難以實現復雜計算。constexpr的出現徹底改變了這一局面。

1.2 constexpr的核心價值

constexpr(常量表達式)是C++11引入的關鍵字,用于聲明可在編譯期求值的表達式或函數。其核心價值體現在:

  1. 性能提升:將計算從運行時轉移到編譯期,減少程序啟動時間和運行時開銷。
  2. 類型安全:編譯期計算的結果是常量,可用于數組大小、模板參數等需要編譯期常量的場景。
  3. 錯誤檢測:編譯期計算能在編譯階段暴露計算邏輯錯誤,避免運行時崩潰。
  4. 代碼簡化:替代復雜的模板元編程,用接近普通代碼的語法實現編譯期計算。

1.3 constexpr的版本演進

constexpr并非一成不變,其功能隨C++標準不斷增強:

標準版本核心增強點示例
C++11引入constexpr,支持簡單函數(單return語句,無循環)constexpr int add(int a, int b) { return a + b; }
C++14放寬限制:允許函數內有局部變量、循環、多return語句constexpr int factorial(int n) { int res=1; for(int i=2;i<=n;++i) res*=i; return res; }
C++17支持if constexpr(編譯期條件分支)、std::array等容器的編譯期操作constexpr auto get_val(bool b) { if constexpr(b) return 1; else return 2.0; }
C++20大幅擴展:支持constexpr動態內存分配、lambda表達式、虛函數等constexpr auto make_vec() { std::vector<int> v={1,2}; return v; }

現代C++中,constexpr已成為編譯期計算的首選工具,功能強大且語法簡潔。

二、constexpr基礎:變量與函數

2.1 constexpr變量

constexpr變量是編譯期可求值的常量,必須滿足:

  • 聲明時初始化
  • 初始化表達式是常量表達式
  • 類型是字面類型(Literal Type,可在編譯期構造的類型)
基本用法
#include <iostream>int main() {// 基礎類型constexpr變量constexpr int a = 10;  // 正確:初始化表達式是常量constexpr int b = a * 2;  // 正確:a是constexpr,表達式是常量// 錯誤示例// int c = 20;// constexpr int d = c;  // 錯誤:c不是常量表達式// 用于需要編譯期常量的場景int arr[a];  // 正確:a是constexpr,可作為數組大小(C99變長數組的C++常量替代)std::cout << "數組大小:" << sizeof(arr)/sizeof(int) << "\n";  // 輸出:10return 0;
}
constexpr與const的區別

constconstexpr都可用于聲明常量,但本質不同:

  • const:表示變量"只讀",初始化表達式可在運行時求值(如const int x = rand();)。
  • constexpr:表示變量"編譯期可求值",初始化表達式必須是常量表達式。
const int x = 10;  // 可能在編譯期或運行時初始化(取決于上下文)
constexpr int y = 10;  // 必須在編譯期初始化const int z = x + y;  // z是const,但初始化依賴x和y(若x是運行時常量,z也是運行時常量)
constexpr int w = x + y;  // 僅當x和y都是constexpr時才合法

結論:constexpr是"更強的const"——所有constexpr變量都是const,但并非所有const變量都是constexpr

2.2 constexpr函數

constexpr函數是可在編譯期或運行時調用的函數。當傳入的參數是常量表達式時,函數在編譯期求值;當傳入運行時變量時,函數在運行時求值。

C++11中的constexpr函數(基礎版)

C++11對constexpr函數有嚴格限制:

  • 函數體只能有一條return語句
  • 不能包含局部變量(除參數外)
  • 不能有循環、分支(if)等控制流語句
  • 只能調用其他constexpr函數
// C++11兼容的constexpr函數
constexpr int add(int a, int b) {return a + b;  // 單return語句,無其他邏輯
}constexpr int square(int x) {return x * x;  // 調用乘法運算符(隱式constexpr)
}int main() {constexpr int res1 = add(3, 5);  // 編譯期求值:8int x = 4;int res2 = add(x, 5);  // 運行時求值:x + 5(x是變量)static_assert(res1 == 8, "編譯期斷言失敗");  // 正確:res1是編譯期常量return 0;
}
C++14對constexpr函數的擴展

C++14大幅放寬了constexpr函數的限制,使其更接近普通函數:

  • 允許局部變量(必須是constexpr或初始化后不再修改)
  • 允許循環(forwhile
  • 允許多return語句
  • 允許條件分支(if-else
// C++14起支持的constexpr函數(含循環)
constexpr int factorial(int n) {if (n <= 1) return 1;  // 條件分支int res = 1;  // 局部變量for (int i = 2; i <= n; ++i) {  // 循環res *= i;}return res;  // 多return路徑
}int main() {constexpr int f5 = factorial(5);  // 編譯期求值:120int n = 6;int f6 = factorial(n);  // 運行時求值:720(n是變量)static_assert(f5 == 120, "階乘計算錯誤");  // 正確return 0;
}

這一擴展使constexpr函數的實用性大幅提升,基本可替代簡單的模板元編程。

C++17的if constexpr(編譯期條件分支)

C++17引入if constexpr,允許在constexpr函數中根據編譯期條件選擇執行路徑,未選中的分支會被編譯器完全忽略(而非僅不執行)。

#include <type_traits>// 根據類型選擇不同的編譯期計算邏輯
template <typename T>
constexpr auto compute(T val) {if constexpr (std::is_integral_v<T>) {return val * 2;  // 整數類型:乘以2} else if constexpr (std::is_floating_point_v<T>) {return val / 2.0;  // 浮點類型:除以2} else {return val;  // 其他類型:直接返回}
}int main() {constexpr int res1 = compute(10);  // 編譯期求值:20(整數分支)constexpr double res2 = compute(3.14);  // 編譯期求值:1.57(浮點分支)constexpr const char* res3 = compute("hello");  // 編譯期求值:"hello"(其他分支)static_assert(res1 == 20 && res2 == 1.57, "計算錯誤");return 0;
}

if constexpr與普通if的核心區別:普通if的所有分支都需編譯通過(即使運行時不執行),而if constexpr的未選中分支可包含語法正確但不匹配當前類型的代碼(如對整數類型調用size()方法)。

三、constexpr進階:類與數據結構

constexpr不僅適用于變量和函數,還可用于類、構造函數、成員函數,實現編譯期的對象創建和操作。

3.1 constexpr構造函數與constexpr對象

C++11起,類可定義constexpr構造函數,用于在編譯期創建對象。constexpr構造函數需滿足:

  • 函數體只能初始化成員變量(C++11),或包含簡單邏輯(C++14起)
  • 所有成員變量必須在初始化列表中初始化(C++11)
  • 不能有virtual函數(C++20前)
// 帶constexpr構造函數的類
class Point {
private:int x_, y_;
public:// constexpr構造函數(C++11起支持)constexpr Point(int x, int y) : x_(x), y_(y) {}  // 僅初始化成員變量// constexpr成員函數(返回成員變量)constexpr int x() const { return x_; }constexpr int y() const { return y_; }// C++14起:constexpr成員函數可修改成員變量(需對象是mutable或在編譯期修改)constexpr void set_x(int x) { x_ = x; }
};int main() {// 編譯期創建Point對象constexpr Point p1(3, 4);static_assert(p1.x() == 3 && p1.y() == 4, "初始化錯誤");// 編譯期修改對象(C++14起)constexpr Point p2(0, 0);constexpr Point p3 = [](){ Point p(0, 0);p.set_x(5);  // 調用constexpr成員函數修改xreturn p;}();  // 立即調用的constexpr lambda(C++17起)static_assert(p3.x() == 5, "修改錯誤");return 0;
}

3.2 constexpr與標準容器

C++17起,部分標準容器(如std::arraystd::string_view)支持constexpr操作,可在編譯期創建和操作:

#include <array>
#include <string_view>// 編譯期初始化std::array并計算總和
constexpr auto make_array_and_sum() {std::array<int, 5> arr = {1, 2, 3, 4, 5};  // constexpr容器int sum = 0;for (int i = 0; i < arr.size(); ++i) {sum += arr[i];  // 編譯期遍歷}return sum;
}// 編譯期字符串處理(C++17 string_view)
constexpr bool starts_with_hello(std::string_view s) {return s.substr(0, 5) == "hello";  // 編譯期字符串比較
}int main() {constexpr int total = make_array_and_sum();static_assert(total == 15, "數組求和錯誤");constexpr bool res1 = starts_with_hello("hello world");  // trueconstexpr bool res2 = starts_with_hello("hi there");  // falsestatic_assert(res1 && !res2, "字符串判斷錯誤");return 0;
}

C++20進一步擴展了constexpr對容器的支持,std::vectorstd::string等動態容器也可在編譯期使用(需注意:編譯期動態內存分配在程序運行時會被優化掉,不會產生實際的堆操作)。

3.3 自定義constexpr數據結構

結合constexpr函數和類,可實現編譯期可用的自定義數據結構,如鏈表、棧、隊列等:

// 編譯期鏈表節點
template <int Val, typename Next = void>
struct Node {static constexpr int value = Val;using next = Next;
};// 編譯期鏈表長度計算
template <typename List>
constexpr int length() {if constexpr (std::is_same_v<typename List::next, void>) {return 1;  // 尾節點} else {return 1 + length<typename List::next>();  // 遞歸計算}
}// 編譯期鏈表求和
template <typename List>
constexpr int sum() {if constexpr (std::is_same_v<typename List::next, void>) {return List::value;} else {return List::value + sum<typename List::next>();}
}int main() {// 編譯期構建鏈表:1 -> 2 -> 3using List = Node<1, Node<2, Node<3>>>;constexpr int len = length<List>();  // 3constexpr int total = sum<List>();   // 6static_assert(len == 3 && total == 6, "鏈表操作錯誤");return 0;
}

四、編譯期計算實戰案例

constexpr的應用場景廣泛,從簡單的常量定義到復雜的編譯期算法,都能發揮重要作用。以下是幾個典型實戰案例:

4.1 編譯期素數判斷與素數表生成

素數判斷是經典的計算密集型任務,將其轉移到編譯期可顯著提升運行時性能:

#include <array>// 編譯期判斷是否為素數
constexpr bool is_prime(int n) {if (n <= 1) return false;if (n == 2) return true;if (n % 2 == 0) return false;for (int i = 3; i * i <= n; i += 2) {  // 僅檢查奇數if (n % i == 0) return false;}return true;
}// 編譯期生成前N個素數的數組
template <int N>
constexpr auto generate_primes() {std::array<int, N> primes{};int count = 0;int num = 2;while (count < N) {if (is_prime(num)) {primes[count++] = num;}num++;}return primes;
}int main() {// 編譯期生成前10個素數constexpr auto primes = generate_primes<10>();// 運行時直接使用編譯期結果for (int p : primes) {std::cout << p << " ";  // 輸出:2 3 5 7 11 13 17 19 23 29}return 0;
}

這一案例中,generate_primes<10>()在編譯期完成計算,運行時僅需遍歷數組,避免了重復計算。

4.2 編譯期字符串哈希

字符串哈希常用于哈希表、緩存鍵等場景,編譯期計算哈希值可在運行時直接使用,提升效率:

// 編譯期字符串哈希(FNV-1a算法)
constexpr uint32_t fnv1a_hash(const char* str, uint32_t hash = 0x811c9dc5) {return (*str == '\0') ? hash : fnv1a_hash(str + 1, (hash ^ static_cast<uint32_t>(*str)) * 0x01000193);
}int main() {// 編譯期計算哈希值constexpr uint32_t hash1 = fnv1a_hash("hello");constexpr uint32_t hash2 = fnv1a_hash("world");// 運行時比較哈希值(直接比較常量)if (hash1 == fnv1a_hash("hello")) {  // 編譯期已知truestd::cout << "哈希匹配\n";}return 0;
}

在實際應用中,可將編譯期哈希與switch語句結合,實現高效的字符串分支判斷(傳統switch不支持字符串,但支持整數哈希值)。

4.3 編譯期配置校驗

在大型項目中,配置參數的合法性校驗可放在編譯期,避免運行時因配置錯誤導致崩潰:

// 編譯期配置結構體
struct Config {int max_connections;  // 最大連接數(必須>0且<=1000)int timeout_ms;       // 超時時間(必須>=100ms)bool enable_log;      // 是否啟用日志
};// 編譯期校驗配置合法性
constexpr bool validate_config(const Config& cfg) {bool valid = true;if (cfg.max_connections <= 0 || cfg.max_connections > 1000) {valid = false;}if (cfg.timeout_ms < 100) {valid = false;}return valid;
}// 安全創建配置(僅當配置合法時編譯通過)
template <Config Cfg>
constexpr Config make_safe_config() {static_assert(validate_config(Cfg), "配置不合法!");return Cfg;
}int main() {// 合法配置:編譯通過constexpr Config valid_cfg = make_safe_config<Config{500, 200, true}>();// 非法配置:編譯失敗(觸發static_assert)// constexpr Config invalid_cfg = make_safe_config<Config{-1, 50, false}>();return 0;
}

這一模式在嵌入式開發、驅動程序等對可靠性要求高的場景中尤為重要。

4.4 編譯期矩陣運算

科學計算中的矩陣運算(如乘法、轉置)可在編譯期完成,尤其適合固定大小的小矩陣:

#include <array>// 編譯期矩陣轉置(N行M列 -> M行N列)
template <typename T, int N, int M>
constexpr auto transpose(const std::array<std::array<T, M>, N>& mat) {std::array<std::array<T, N>, M> res{};for (int i = 0; i < N; ++i) {for (int j = 0; j < M; ++j) {res[j][i] = mat[i][j];}}return res;
}// 編譯期矩陣乘法(N×M 乘以 M×P -> N×P)
template <typename T, int N, int M, int P>
constexpr auto multiply(const std::array<std::array<T, M>, N>& a, const std::array<std::array<T, P>, M>& b) {std::array<std::array<T, P>, N> res{};for (int i = 0; i < N; ++i) {for (int j = 0; j < P; ++j) {for (int k = 0; k < M; ++k) {res[i][j] += a[i][k] * b[k][j];}}}return res;
}int main() {// 編譯期定義矩陣constexpr std::array<std::array<int, 2>, 2> a = {{{1, 2},{3, 4}}};// 編譯期轉置constexpr auto a_t = transpose(a);  // 2×2矩陣轉置// 編譯期乘法(a × a_t)constexpr auto a_mul_at = multiply(a, a_t);// 驗證結果(編譯期斷言)static_assert(a_mul_at[0][0] == 5 && a_mul_at[1][1] == 25, "矩陣運算錯誤");return 0;
}

五、constexpr的性能分析與限制

5.1 編譯期計算vs運行時計算:性能對比

編譯期計算的核心優勢是零運行時開銷,但可能增加編譯時間。以下是一個性能對比示例:

#include <chrono>
#include <iostream>// 斐波那契數列計算(遞歸實現)
constexpr int fib(int n) {return (n <= 1) ? n : fib(n - 1) + fib(n - 2);
}int main() {// 編譯期計算fib(30)constexpr int fib30_compile = fib(30);// 運行時計算fib(30)auto start = std::chrono::high_resolution_clock::now();int fib30_runtime = fib(30);auto end = std::chrono::high_resolution_clock::now();std::cout << "編譯期結果:" << fib30_compile << "\n";std::cout << "運行時結果:" << fib30_runtime << "\n";std::cout << "運行時耗時:" << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()<< " us\n";  // 約數百微秒(遞歸實現效率低)return 0;
}

運行結果顯示:編譯期計算的結果直接可用,運行時無需消耗時間。對于多次調用的場景(如循環中調用fib(30)),編譯期計算的優勢更明顯。

5.2 編譯時間與運行時間的平衡

編譯期計算并非"計算量越大越好",過度復雜的編譯期計算會顯著增加編譯時間,降低開發效率。平衡原則:

  1. 小數據量、高頻調用:優先編譯期計算(如配置參數、常量哈希)。
  2. 大數據量、低頻調用:傾向運行時計算(如大型矩陣運算、復雜字符串處理)。
  3. 開發迭代快的項目:控制編譯期計算復雜度,避免每次編譯耗時過長。
  4. 發布版本:可啟用更復雜的編譯期優化,提升最終產品性能。

5.3 constexpr的當前限制

盡管constexpr功能不斷增強,仍存在一些限制(隨標準演進逐步減少):

  1. C++20前不支持動態內存管理new/delete在C++20前不能用于constexpr函數。
  2. 虛函數支持有限:C++20起允許constexpr虛函數,但實現復雜且效率可能不高。
  3. I/O操作不可用:編譯期計算不能進行文件讀寫、控制臺輸出等I/O操作。
  4. 部分標準庫函數不支持:并非所有標準庫函數都標記為constexpr(如std::sort在C++20起支持constexpr)。
  5. 調試困難:編譯期計算的錯誤信息通常不如運行時調試直觀,需依賴static_assert輔助。

六、最佳實踐與調試技巧

6.1 constexpr使用最佳實踐

  1. 優先使用constexpr替代宏:宏缺乏類型檢查,constexpr常量更安全。

    #define MAX_SIZE 100  // 不推薦
    constexpr int max_size = 100;  // 推薦
    
  2. 函數參數盡量使用值傳遞constexpr函數的參數需在編譯期確定,值傳遞更易滿足常量表達式要求。

  3. 結合auto推導返回類型:復雜constexpr函數的返回類型難以手動聲明,auto可簡化代碼。

    constexpr auto complex_calc(int x) {// 復雜計算...return result;  // auto自動推導類型
    }
    
  4. 用static_assert驗證編譯期計算結果:在開發階段確保計算邏輯正確。

    constexpr int res = my_constexpr_func(5);
    static_assert(res == 25, "計算錯誤:預期25");  // 提前暴露錯誤
    
  5. 避免在constexpr函數中使用全局變量:全局變量可能不是編譯期常量,導致函數無法在編譯期求值。

6.2 調試constexpr代碼的技巧

constexpr代碼的調試比普通代碼更困難(無法在編譯期設置斷點),可采用以下技巧:

  1. 分步驗證:將復雜constexpr函數拆分為多個小函數,用static_assert驗證中間結果。

    constexpr int step1(int x) { /* ... */ }
    constexpr int step2(int x) { /* ... */ }
    constexpr int complex_func(int x) { return step2(step1(x)); }static_assert(step1(5) == 10, "step1錯誤");  // 驗證中間步驟
    static_assert(complex_func(5) == 20, "最終結果錯誤");
    
  2. 運行時復現編譯期邏輯:編寫與constexpr函數邏輯一致的普通函數,在運行時調試后再遷移。

    // 先調試普通函數
    int factorial_runtime(int n) { /* 與constexpr版本相同 */ }// 確認正確后改為constexpr
    constexpr int factorial(int n) { /* 同上 */ }
    
  3. 利用編譯器診斷信息:現代編譯器(如GCC 10+、Clang 12+)對constexpr錯誤的提示越來越清晰,仔細分析錯誤信息通常能定位問題。

  4. 限制編譯期計算深度:遞歸constexpr函數若深度過深,可能觸發編譯器的遞歸限制(可通過編譯器參數調整,如GCC的-fconstexpr-depth=10000)。

七、總結

constexpr是C++編譯期計算的核心工具,從C++11的基礎常量表達式到C++20的全面增強,它徹底改變了開發者處理編譯期邏輯的方式。通過將計算從運行時轉移到編譯期,constexpr不僅能提升程序性能,還能在編譯階段暴露錯誤,增強代碼可靠性。

隨著C++標準的持續演進,constexpr的功能將進一步完善,有望覆蓋更多編譯期計算場景。掌握constexpr已成為現代C++開發者提升代碼質量和性能的必備技能,無論是系統開發、游戲引擎還是嵌入式編程,編譯期計算都能發揮關鍵作用。

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

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

相關文章

【micro:bit】從入門到放棄(一):在線、離線版本的使用

1、離線版 micro:bit 1)下載地址 https://makecode.microbit.org/offline-app 2)雙擊安裝包,makecode-microbit-setup-win64.exe,自動安裝,安裝成功后圖標如下圖所示 3)運行程序,查看版本信息 4)主界面如下 5)編程界面 點擊“新建項目”或者“導入”進入編程界…

Flink Forward Asia 2025 主旨演講精彩回顧

作為 Apache Flink 社區備受矚目的年度盛會之一&#xff0c;由阿里云承辦的 Flink Forward Asia 2025 于 7 月 3 日在新加坡正式拉開帷幕。From Real-Time Data Analytics to Real-Time AI&#xff0c;Flink 生態全面擁抱 AI本次大會上&#xff0c;Apache Flink 中文社區發起人…

車道偏離預警(LDW)功能介紹

車道偏離預警&#xff08;LDW&#xff09;功能介紹 LDW功能 通過攝像頭監測前方車道線&#xff0c;當車輛偏離車道線時&#xff0c;系統發出報警提醒。 系統框圖報警條件 最早報警線最遲報警線報警臨界線 設置在 最早/最遲報警線 之間接口定義 輸入/輸出系統算法 橫向偏離速度模…

軟考(軟件設計師)計算機網絡-網絡層

obsidian做markdown筆記太爽了&#xff0c;康奈爾模板筆記看起來舒服&#xff0c;CSDN試了幾種方式&#xff0c;不支持&#xff0c;只能貼圖了&#xff0c;將就看吧&#x1f60f;&#xff08;狗頭保命&#xff09;工作原理圖解 #mermaid-svg-e5Tgpt26jUftujKn {font-family:&qu…

nginx反向代理實現跨域請求

記錄一個項目中遇到的跨域請求問題&#xff0c;解決跨域問題無非幾種辦法&#xff1a;1、后端解決&#xff0c;推薦的做法&#xff0c;可以看我之前寫的文章&#xff0c;fastadmin的后臺配置跨域&#xff1b;2、前端配置proxy代理&#xff08;開發環境用&#xff09;&#xff1…

利用Wisdom SSH高效搭建CI/CD工作流

在軟件開發流程中&#xff0c;CI/CD工作流對于提升效率與確保質量起著關鍵作用。Wisdom SSH作為一款強大工具&#xff0c;其官網為ssh.wisdomheart.cn&#xff0c;借助AI助手能大幅簡化CI/CD工作流的搭建過程。假設服務器已完成基礎配置&#xff0c;下面為您介紹如何利用Wisdom…

深度學習-循環神經網絡RNN

文章目錄序列模型循環神經網絡案例詞的表示輸出的表示矩陣運算表示交叉熵損失時間反向傳播算法BPTT梯度消失與梯度爆炸GRULSTM總結序列模型 循環神經網絡 st是上一個隱層的輸出&#xff0c;體現序列數據之間有很強的關聯性。 案例 > S0是初始輸入&#xff0c;一般是0&#…

【Linux網絡編程】Socket - TCP

目錄 V1版本 - Echo Server 初始化服務器 啟動服務器 客戶端 一些BUG與問題 解決服務器無法一次處理多個請求的問題 多進程版本 多線程版本 線程池版本 V2版本 - 多線程遠程執行命令 V1版本 - Echo Server 初始化服務器 TCP大部分內容與UDP是相同的&#xff0c;我們…

知識圖譜構建簡單分享

最近系統性地學習了知識圖譜構建的關鍵技術&#xff0c;并結合醫療領域知識&#xff0c;完成了一個醫療知識圖譜項目的實踐。以下是整理的項目架構&#xff0c;歡迎交流指正。說明&#xff1a;當前項目實際實現主要應用了數據預處理、模型設計與預訓練、模型優化與測試等核心技…

MCU中的系統控制器(System Controller)是什么?

MCU中的系統控制器&#xff08;System Controller&#xff09;是什么&#xff1f; 在微控制器&#xff08;MCU&#xff09;中&#xff0c;系統控制器&#xff08;System Controller&#xff09;是一個關鍵模塊&#xff0c;負責管理和協調MCU內部的核心功能&#xff0c;確保系統…

【Datawhale夏令營】用AI做帶貨視頻評論分析

文本分類、文本聚類 基礎庫&#xff1a; pandas, sklearn功能&#xff1a; 商品識別、情感分析、評論聚類商品識別&#xff1a; 視頻文本信息&#xff0c;預測推廣商品名稱 & 情感分析&#xff1a;四個維度&#xff08;情感傾向、用戶場景、用戶疑問、用戶建議&#xff09…

[Meetily后端框架] AI摘要結構化 | `SummaryResponse`模型 | Pydantic庫 | vs marshmallow庫

第3章&#xff1a;摘要數據結構&#xff08;Pydantic庫&#xff09; 歡迎回來&#xff01; 在之前的第2章&#xff1a;API文檔中&#xff0c;我們知道API網關提供了端點 而API文檔準確告訴我們如何與這些端點通信&#xff0c;包括需要發送的數據格式和期望接收的數據格式。 …

深度學習 tensor及其相關操作

目錄 Tensor 概念 數據類型 創建tensor 基本創建方式 1、 torch.tensor() 2、torch.Tensor() 3、torch.IntTensor() 等 創建線性張量和隨機張量 1、創建線性張量 2、創建隨機張量 切換設備 類型轉換 與 Numpy 數據轉換 1、張量轉 Numpy 2、Numpy 轉張量 tenso…

如何將FPGA設計的驗證效率提升1000倍以上(4)

本文為系列文章的完結篇。用戶應用設計中的信號&#xff0c;在經歷編譯器的多次迭代優化之后&#xff0c;在FPGA芯片內部運行時&#xff0c;可能已經被重新命名、“改頭換面”或“機里機氣”。要想以人工經驗進行追蹤&#xff0c;構建目標寄存器信號與RTL設計源碼之間的映射關系…

Linux驅動11 --- buildroot雜項驅動開發方法

目錄 一、Buildroot 1.1介紹 文件系統 1.一個完整的操作系統需要包含大量的文件 2.在嵌入式開發中目前應用最廣泛的文件系統制作工具就是 buildroot&#xff0c;busybox 3.buildroot 制作文件系統&#xff08;了解&#xff09; 二、雜項驅動編程 1.1 驅動編程做的內容 2.2…

Unity物理系統由淺入深第三節:物理引擎底層原理剖析

Unity物理系統由淺入深第一節&#xff1a;Unity 物理系統基礎與應用 Unity物理系統由淺入深第二節&#xff1a;物理系統高級特性與優化 Unity物理系統由淺入深第三節&#xff1a;物理引擎底層原理剖析 Unity物理系統由淺入深第四節&#xff1a;物理約束求解與穩定性 Unity 物理…

Docker一鍵安裝中間件(RocketMq、Nginx、MySql、Minio、Jenkins、Redis)腳步

1、Docker安裝RocketMq 2、Docker安裝Nginx 3、Docker安裝MySql 4、Docker安裝Minio 5、Docker安裝jenkins 6、Docker安裝Redis 1、Docker安裝RocketMq #!/bin/bash# 定義變量 NAMESRV_CONTAINER"rocketmq-namesrv" BROKER_CONTAINER"rocketmq-broker&quo…

WPF學習筆記(27)科學計算器

科學計算器1. 前端界面2. 功能代碼3. 效果展示1. 前端界面 <Window x:Class"Cal.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http:/…

【Linux系列】unzip file 命令

博客目錄掌握 unzip -o 命令&#xff1a;高效解壓并覆蓋文件的完整指南一、unzip 命令基礎二、-o 選項的核心作用三、典型應用場景四、與其他選項的組合使用五、注意事項與風險防范六、替代方案與高級技巧掌握 unzip -o 命令&#xff1a;高效解壓并覆蓋文件的完整指南 在日常的…

1965–2022年中國大陸高分辨率分部門用水數據集,包含:灌溉用水、工業制造用水、生活用水和火電冷卻

1965–2022年中國大陸高分辨率部門用水數據集 高質量用水數據集對推進變化環境下的水資源研究至關重要。然而&#xff0c;現有中國用水數據通常按行政區劃或流域匯總&#xff0c;時空分辨率不足&#xff0c;難以支撐人類用水模式及時空變化特征的精細化分析。為此&#xff0c;…