欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實(shí)現(xiàn)多線程并發(fā)場景下的同步方法

 更新時(shí)間:2025年02月18日 10:06:14   作者:kucupung  
在C++中實(shí)現(xiàn)多線程并發(fā)場景下的同步方法,包括使用互斥鎖、獨(dú)占鎖、共享鎖和原子操作的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下

如果在多線程程序中對全局變量的訪問沒有進(jìn)行適當(dāng)?shù)耐娇刂疲ɡ缡褂没コ怄i、原子變量等),會導(dǎo)致多個(gè)線程同時(shí)訪問和修改全局變量時(shí)發(fā)生競態(tài)條件(race condition)。這種競態(tài)條件可能會導(dǎo)致一系列不確定和嚴(yán)重的后果。

在C++中,可以通過使用互斥鎖(mutex)、原子操作、讀寫鎖來實(shí)現(xiàn)對全局變量的互斥訪問。

一、缺乏同步控制造成的后果

1. 數(shù)據(jù)競爭(Data Race)

數(shù)據(jù)競爭發(fā)生在多個(gè)線程同時(shí)訪問同一個(gè)變量,并且至少有一個(gè)線程在寫該變量時(shí)沒有進(jìn)行同步。由于缺少同步機(jī)制,多個(gè)線程對全局變量的操作可能會相互干擾,導(dǎo)致變量的值不可預(yù)測。

示例:

#include <iostream>
#include <thread>

int globalVar = 0;

void increment() {
    globalVar++;
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join();
    t2.join();

    std::cout << "Global variable: " << globalVar << std::endl;
    return 0;
}

后果:

  • 上面的代碼中,globalVar++ 并不是一個(gè)原子操作。它由多個(gè)步驟組成:讀取值、增加值、寫回。在這段代碼中,t1 和 t2 可能會同時(shí)讀取globalVar的值,導(dǎo)致兩個(gè)線程同時(shí)修改它的值,最終的結(jié)果會小于預(yù)期的2。這就是典型的數(shù)據(jù)競爭。

2. 不一致的狀態(tài)(Inconsistent State)

在沒有同步控制的情況下,多個(gè)線程可能會對全局變量進(jìn)行同時(shí)讀寫操作,導(dǎo)致變量處于不一致的狀態(tài)。例如,多個(gè)線程可能會同時(shí)讀取和修改相同的變量,導(dǎo)致最終狀態(tài)不符合預(yù)期。

示例: 假設(shè)你有一個(gè)程序要求維護(hù)一個(gè)全局的計(jì)數(shù)器。如果沒有加鎖來確保線程安全,兩個(gè)線程同時(shí)執(zhí)行時(shí),計(jì)數(shù)器可能會被寫成一個(gè)無意義的值。

#include <iostream>
#include <thread>

int counter = 0;

void increment() {
    for (int i = 0; i < 100000; ++i) {
        counter++;  // 非線程安全操作
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

    t1.join();
    t2.join();

    std::cout << "Counter: " << counter << std::endl;
    return 0;
}

后果:

  • 在沒有同步的情況下,counter++ 可能會導(dǎo)致多個(gè)線程在同一時(shí)刻讀取到相同的計(jì)數(shù)器值,并同時(shí)將相同的更新值寫回變量,這會使得counter的最終值遠(yuǎn)小于預(yù)期的200000。
  • 這可能會導(dǎo)致程序的業(yè)務(wù)邏輯錯(cuò)誤,特別是如果全局變量用作關(guān)鍵狀態(tài)的標(biāo)識。

3. 崩潰或程序未定義行為

由于數(shù)據(jù)競爭或者不一致的狀態(tài),程序可能會進(jìn)入一個(gè)不可預(yù)測的狀態(tài),導(dǎo)致崩潰。全局變量的值在多線程的競爭中可能會發(fā)生損壞,從而導(dǎo)致未定義的行為(undefined behavior)。

例如:

  • 訪問已釋放內(nèi)存:一個(gè)線程修改了全局變量并釋放了相關(guān)內(nèi)存,但其他線程仍然試圖訪問該內(nèi)存。
  • 內(nèi)存覆蓋:多個(gè)線程同時(shí)修改全局變量,導(dǎo)致不同線程的操作互相覆蓋,從而引發(fā)崩潰。

二、互斥鎖std::mutex實(shí)現(xiàn)同步

std::mutex 是C++標(biāo)準(zhǔn)庫中的一種機(jī)制,用于避免多個(gè)線程同時(shí)訪問同一個(gè)資源(如全局變量)時(shí)發(fā)生競爭條件。

下面是一個(gè)示例,展示了如何使用std::mutex來保護(hù)全局變量:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;  // 定義全局互斥鎖
int globalVar = 0;  // 定義全局變量

void threadFunction() {
    std::lock_guard<std::mutex> lock(mtx);  // 上鎖,確?;コ?
    // 訪問和修改全局變量
    ++globalVar;
    std::cout << "Global variable: " << globalVar << std::endl;
    // 鎖會在lock_guard離開作用域時(shí)自動釋放
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    t1.join();
    t2.join();

    return 0;
}

說明:

  • std::mutex: 用于保護(hù)共享資源(如全局變量)。
  • std::lock_guard<std::mutex>: 是一個(gè)RAII風(fēng)格的封裝器,它在構(gòu)造時(shí)自動上鎖,在析構(gòu)時(shí)自動解鎖,確保了線程安全。
  • threadFunction中,每個(gè)線程在訪問globalVar之前都會先獲得互斥鎖,這樣就能確保線程之間不會同時(shí)訪問和修改全局變量。

使用std::mutex可以防止不同線程之間因競爭訪問全局變量而引發(fā)的錯(cuò)誤或不一致問題。

有時(shí)如果你需要更細(xì)粒度的控制,還可以考慮使用std::unique_lock,它比std::lock_guard更靈活,允許手動控制鎖的獲取和釋放。

三、獨(dú)占鎖std::unique_lock實(shí)現(xiàn)同步

std::unique_lock 是 C++11 標(biāo)準(zhǔn)庫中的一種互斥鎖包裝器,它提供了比 std::lock_guard 更靈活的鎖管理方式。std::unique_lock 允許手動控制鎖的獲取和釋放,而不僅僅是在對象生命周期結(jié)束時(shí)自動釋放鎖(如 std::lock_guard 所做的那樣)。這使得它比 std::lock_guard 更加靈活,適用于更復(fù)雜的場景,比如需要在同一作用域內(nèi)多次鎖定或解鎖,或者需要在鎖定期間進(jìn)行一些其他操作。

std::unique_lock 的關(guān)鍵特性:

  • 手動控制鎖的獲取和釋放:std::unique_lock 支持手動解鎖和重新鎖定,它比 std::lock_guard 更加靈活。
  • 延遲鎖定和提前解鎖:你可以選擇在對象創(chuàng)建時(shí)延遲鎖定,或者在鎖定后手動釋放鎖。
  • 支持條件變量:std::unique_lock 支持與條件變量一起使用,這是 std::lock_guard 無法做到的。

基本用法:

1. 構(gòu)造時(shí)自動加鎖:

std::unique_lock 默認(rèn)會在構(gòu)造時(shí)自動加鎖。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx);  // 構(gòu)造時(shí)自動上鎖
    std::cout << "Thread is running\n";
    // 臨界區(qū)的操作
    // 鎖會在 lock 對象超出作用域時(shí)自動釋放
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    t1.join();
    t2.join();

    return 0;
}

2. 手動解鎖與重新加鎖:

std::unique_lock 允許你在鎖定期間手動解鎖和重新加鎖,這對于一些需要臨時(shí)釋放鎖的場景非常有用。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx);  // 構(gòu)造時(shí)自動上鎖
    std::cout << "Thread is running\n";
    
    // 臨界區(qū)的操作
    lock.unlock();  // 手動解鎖
    
    std::cout << "Lock released temporarily\n";
    
    // 臨界區(qū)之外的操作
    
    lock.lock();  // 重新加鎖
    
    std::cout << "Lock acquired again\n";
    // 臨界區(qū)操作繼續(xù)進(jìn)行
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    t1.join();
    t2.join();

    return 0;
}

3. 延遲鎖定:

std::unique_lock 也允許你延遲鎖定,通過傳遞一個(gè) std::defer_lock 參數(shù)給構(gòu)造函數(shù)來實(shí)現(xiàn)。這會創(chuàng)建一個(gè)未鎖定的 std::unique_lock,你可以在稍后手動調(diào)用 lock() 來加鎖。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx, std::defer_lock);  // 延遲加鎖
    std::cout << "Thread is preparing to run\n";
    
    // 做一些不需要加鎖的操作
    
    lock.lock();  // 手動加鎖
    std::cout << "Thread is running under lock\n";
    
    // 臨界區(qū)的操作
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    t1.join();
    t2.join();

    return 0;
}

4. 條件變量:

std::unique_lock 是與條件變量一起使用的理想選擇,它支持對互斥鎖的手動解鎖和重新加鎖。這在條件變量的使用場景中非常有用,因?yàn)樵诘却龡l件時(shí)需要解鎖互斥鎖,而在條件滿足時(shí)重新加鎖。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx);  // 上鎖
    while (!ready) {  // 等待 ready 為 true
        cv.wait(lock);  // 等待,自動解鎖并掛起線程
    }
    std::cout << "Thread is running\n";
}

void notify() {
    std::this_thread::sleep_for(std::chrono::seconds(1));  // 模擬一些操作
    std::cout << "Notifying the threads\n";
    std::unique_lock<std::mutex> lock(mtx);  // 上鎖
    ready = true;
    cv.notify_all();  // 通知所有線程
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);

    std::thread notifier(notify);
    
    t1.join();
    t2.join();
    notifier.join();

    return 0;
}

解釋:

  • std::condition_variable 和 std::unique_lock

    • 在 threadFunction 中,cv.wait(lock) 會釋放鎖并等待條件變量的通知。
    • std::unique_lock 能夠在調(diào)用 wait 時(shí)自動釋放鎖,并且在 wait 返回時(shí)會重新加鎖,這使得 std::unique_lock 成為使用條件變量的最佳選擇。
  • cv.notify_all():通知所有等待該條件的線程,thread1 和 thread2 都會在條件滿足時(shí)繼續(xù)執(zhí)行。

四、共享鎖std::shared_mutex實(shí)現(xiàn)同步

std::shared_mutex 是 C++17 引入的一個(gè)同步原語,它提供了一種讀寫鎖機(jī)制,允許多個(gè)線程共享讀取同一資源,而只有一個(gè)線程能夠獨(dú)占寫入該資源。相比于傳統(tǒng)的 std::mutex(只支持獨(dú)占鎖),std::shared_mutex 可以提高并發(fā)性,特別是在讀操作遠(yuǎn)多于寫操作的情況下。

std::shared_mutex 的工作原理:

  • 共享鎖(shared lock):多個(gè)線程可以同時(shí)獲取共享鎖,這意味著多個(gè)線程可以同時(shí)讀取共享資源。多個(gè)線程獲取共享鎖時(shí)不會發(fā)生沖突。
  • 獨(dú)占鎖(unique lock):只有一個(gè)線程可以獲取獨(dú)占鎖,這意味著寫操作會阻塞其他所有操作(無論是讀操作還是寫操作),以保證數(shù)據(jù)的一致性。

使用 std::shared_mutex:

std::shared_mutex 提供了兩種類型的鎖:

  • std::unique_lock<std::shared_mutex>:用于獲取獨(dú)占鎖。
  • std::shared_lock<std::shared_mutex>:用于獲取共享鎖。

1. 基本使用示例:

#include <iostream>
#include <thread>
#include <shared_mutex>
#include <vector>

std::shared_mutex mtx;  // 定義一個(gè) shared_mutex
int sharedData = 0;

void readData(int threadId) {
    std::shared_lock<std::shared_mutex> lock(mtx);  // 獲取共享鎖
    std::cout << "Thread " << threadId << " is reading data: " << sharedData << std::endl;
}

void writeData(int threadId, int value) {
    std::unique_lock<std::shared_mutex> lock(mtx);  // 獲取獨(dú)占鎖
    sharedData = value;
    std::cout << "Thread " << threadId << " is writing data: " << sharedData << std::endl;
}

int main() {
    std::vector<std::thread> threads;

    // 啟動多個(gè)線程進(jìn)行讀取操作
    for (int i = 0; i < 5; ++i) {
        threads.push_back(std::thread(readData, i));
    }

    // 啟動一個(gè)線程進(jìn)行寫入操作
    threads.push_back(std::thread(writeData, 100, 42));

    // 等待所有線程結(jié)束
    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

解釋:

  • 共享鎖 (std::shared_lock):線程 readData 使用 std::shared_lock 獲取共享鎖,這允許多個(gè)線程同時(shí)讀取 sharedData,因?yàn)樽x取操作是線程安全的。
  • 獨(dú)占鎖 (std::unique_lock):線程 writeData 使用 std::unique_lock 獲取獨(dú)占鎖,這確保了只有一個(gè)線程可以寫 sharedData,并且寫操作會阻塞所有其他線程(包括讀操作和寫操作)。

2. 多個(gè)讀線程與單個(gè)寫線程的并發(fā)控制:

在這個(gè)示例中,多個(gè)讀線程可以并行執(zhí)行,因?yàn)樗鼈兌极@取了共享鎖。只有當(dāng)寫線程(獲取獨(dú)占鎖)執(zhí)行時(shí),其他線程(無論是讀線程還是寫線程)會被阻塞。

  • 寫操作:獲取獨(dú)占鎖,所有讀操作和寫操作都會被阻塞,直到寫操作完成。
  • 讀操作:多個(gè)線程可以同時(shí)獲取共享鎖,只有在沒有寫操作時(shí)才會執(zhí)行。

3. 共享鎖與獨(dú)占鎖的沖突:

  • 共享鎖:多個(gè)線程可以同時(shí)獲取共享鎖,只要沒有線程持有獨(dú)占鎖。共享鎖不會阻塞其他共享鎖請求。
  • 獨(dú)占鎖:當(dāng)一個(gè)線程持有獨(dú)占鎖時(shí),其他任何線程的共享鎖或獨(dú)占鎖請求都會被阻塞,直到獨(dú)占鎖釋放。

4. 使用場景:

std::shared_mutex 主要適用于讀多寫少的場景。假設(shè)有一個(gè)資源(如緩存、數(shù)據(jù)結(jié)構(gòu)),它在大部分時(shí)間內(nèi)被多個(gè)線程讀取,但偶爾需要被更新。在這種情況下,std::shared_mutex 可以讓多個(gè)讀操作并行執(zhí)行,同時(shí)避免寫操作導(dǎo)致的不必要的阻塞。

例如:

  • 緩存數(shù)據(jù)讀?。憾鄠€(gè)線程可以并發(fā)讀取緩存中的數(shù)據(jù),而當(dāng)緩存需要更新時(shí),獨(dú)占鎖會確保數(shù)據(jù)一致性。
  • 數(shù)據(jù)庫的并發(fā)查詢和修改:多個(gè)線程可以并發(fā)查詢數(shù)據(jù)庫,但只有一個(gè)線程可以執(zhí)行寫操作。

5. std::shared_mutex 與 std::mutex 比較:

  • std::mutex:提供獨(dú)占鎖,適用于寫操作頻繁且不需要并發(fā)讀的場景。每次加鎖時(shí),其他線程都無法進(jìn)入臨界區(qū)。
  • std::shared_mutex:適用于讀多寫少的場景,允許多個(gè)線程同時(shí)讀取共享資源,但寫操作會阻塞所有其他操作。

6. 性能考慮:

  • 讀操作頻繁時(shí):使用 std::shared_mutex 可以提高并發(fā)性,因?yàn)槎鄠€(gè)線程可以同時(shí)讀取數(shù)據(jù)。
  • 寫操作頻繁時(shí):性能可能會低于 std::mutex,因?yàn)閷懖僮餍枰?dú)占資源并阻塞所有其他操作。

7. 條件變量:

與 std::mutex 一樣,std::shared_mutex 也可以與條件變量(std::condition_variable)一起使用,不過在使用時(shí)要注意,不同的線程需要加鎖和解鎖對應(yīng)的鎖。

#include <iostream>
#include <thread>
#include <shared_mutex>
#include <condition_variable>

std::shared_mutex mtx;
std::condition_variable_any cv;
int sharedData = 0;

void readData() {
    std::shared_lock<std::shared_mutex> lock(mtx);  // 獲取共享鎖
    while (sharedData == 0) {  // 等待數(shù)據(jù)可用
        cv.wait(lock);  // 等待數(shù)據(jù)被寫入
    }
    std::cout << "Reading data: " << sharedData << std::endl;
}

void writeData(int value) {
    std::unique_lock<std::shared_mutex> lock(mtx);  // 獲取獨(dú)占鎖
    sharedData = value;
    std::cout << "Writing data: " << sharedData << std::endl;
    cv.notify_all();  // 通知所有等待的線程
}

int main() {
    std::thread reader(readData);
    std::thread writer(writeData, 42);

    reader.join();
    writer.join();

    return 0;
}

解釋:

  • std::shared_lock:用于共享讀鎖,允許多個(gè)線程同時(shí)讀取。
  • cv.wait(lock):使用共享鎖來等待某些條件的變化。
  • cv.notify_all():通知所有等待線程,喚醒它們繼續(xù)執(zhí)行。

五、std::atomic實(shí)現(xiàn)同步

std::atomic 是 C++11 標(biāo)準(zhǔn)引入的一種類型,用于實(shí)現(xiàn)原子操作。原子操作指的是操作在執(zhí)行過程中不可被中斷,因此能夠保證數(shù)據(jù)的一致性和正確性。

std::atomic 提供了一些基本的原子操作方法,這些操作是不可分割的,保證了在多線程環(huán)境下線程安全。它主要用于數(shù)據(jù)的同步與協(xié)作,避免了傳統(tǒng)同步原語(如鎖、條件變量)所帶來的性能瓶頸。

原子操作的基本概念:

  • 原子性:在執(zhí)行時(shí),操作不能被打斷,保證線程之間對共享變量的操作不會產(chǎn)生競態(tài)條件。
  • 內(nèi)存順序(Memory Ordering):控制操作的執(zhí)行順序和對共享數(shù)據(jù)的可見性,std::atomic 允許通過內(nèi)存順序來顯式指定不同線程間的同步行為。

std::atomic 提供的原子操作:

  • 加載(Load):從原子變量中讀取數(shù)據(jù)。
  • 存儲(Store):將數(shù)據(jù)存儲到原子變量中。

std::atomic 支持的內(nèi)存順序(Memory Ordering):

  • std::memory_order_acquire:確保前面的操作在加載之后執(zhí)行,即它會阻止后續(xù)的操作在此之前執(zhí)行。
  • std::memory_order_release:確保后面的操作在存儲之前執(zhí)行,即它會阻止前面的操作在此之后執(zhí)行。

通常情況下,在使用 std::atomic 進(jìn)行同步時(shí),使用 memory_order_release 在 store 操作時(shí),使用 memory_order_acquire 在 load 操作時(shí),是一種常見的模式,特別是在生產(chǎn)者-消費(fèi)者模式或者其他類似的同步模式下。

memory_order_release 和 memory_order_acquire 一般搭配使用。

這種組合是為了確保 內(nèi)存順序的一致性,并且保證數(shù)據(jù)正確的可見性。具體來說:

  • memory_order_release:在執(zhí)行 store 操作時(shí),它會確保在 store 之前的所有操作(如數(shù)據(jù)寫入)不會被重排序到 store 之后,保證當(dāng)前線程的寫操作對其他線程是可見的。因此,store 操作保證所有前置的寫操作都會在這個(gè) store 完成后被其他線程看到。

  • memory_order_acquire:在執(zhí)行 load 操作時(shí),它會確保在 load 之后的所有操作(如數(shù)據(jù)讀?。┎粫恢嘏判虻?nbsp;load 之前,保證當(dāng)前線程在讀取共享數(shù)據(jù)后,后續(xù)的操作可以看到正確的數(shù)據(jù)。在 load 之前的所有操作(包括對共享變量的寫入)會在讀取這個(gè)值之后對當(dāng)前線程可見。

這兩者配合使用,確保了線程間的同步,避免了數(shù)據(jù)競態(tài)條件。

具體場景

考慮一個(gè)生產(chǎn)者-消費(fèi)者模型,生產(chǎn)者負(fù)責(zé)寫入數(shù)據(jù)并通知消費(fèi)者,消費(fèi)者負(fù)責(zé)讀取數(shù)據(jù)并處理。

示例:

#include <iostream>
#include <atomic>
#include <thread>

std::atomic<int> data(0);
std::atomic<bool> ready(false);

void consumer() {
    while (!ready.load(std::memory_order_acquire)) {
        // 等待 ready 為 true
    }
    std::cout << "Data: " << data.load(std::memory_order_relaxed) << std::endl;
}

void producer() {
    data.store(42, std::memory_order_relaxed);  // 寫數(shù)據(jù)
    ready.store(true, std::memory_order_release);  // 設(shè)置 ready 為 true
}

int main() {
    std::thread t1(consumer);
    std::thread t2(producer);

    t1.join();
    t2.join();

    return 0;
}

解釋:

  • ready.store(true, std::memory_order_release):生產(chǎn)者線程在寫入 ready 時(shí)使用 memory_order_release,這意味著在 ready 設(shè)置為 true 之后,所有在此之前的操作(如對 data 的寫入)對消費(fèi)者線程是可見的。

  • ready.load(std::memory_order_acquire):消費(fèi)者線程在讀取 ready 時(shí)使用 memory_order_acquire,這意味著消費(fèi)者線程在讀取 ready 后,確保它能夠看到生產(chǎn)者線程在 store ready 之前所做的所有修改(如 data 的值)。

這種組合保證了生產(chǎn)者線程的寫操作(例如 data.store(42))對于消費(fèi)者線程是可見的,且在讀取 ready 后,消費(fèi)者線程可以安全地讀取到更新后的 data。

到此這篇關(guān)于C++實(shí)現(xiàn)多線程并發(fā)場景下的同步方法的文章就介紹到這了,更多相關(guān)C++ 多線程并發(fā)同步內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中STL的常用算法總結(jié)

    C++中STL的常用算法總結(jié)

    這篇文章主要介紹了C++?STL中一些常見算法的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • C++構(gòu)造函數(shù)+復(fù)制構(gòu)造函數(shù)+重載等號運(yùn)算符調(diào)用

    C++構(gòu)造函數(shù)+復(fù)制構(gòu)造函數(shù)+重載等號運(yùn)算符調(diào)用

    這篇文章主要介紹了C++構(gòu)造函數(shù)+復(fù)制構(gòu)造函數(shù)+重載等號運(yùn)算符調(diào)用,文章敘述詳細(xì),具有一定的的參考價(jià)值,需要的小伙伴可以參考一下
    2022-03-03
  • C++使用動態(tài)內(nèi)存分配的原因解說

    C++使用動態(tài)內(nèi)存分配的原因解說

    這篇文章主要介紹了C++使用動態(tài)內(nèi)存分配的原因解說,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • C語言進(jìn)階之字符串查找?guī)旌瘮?shù)詳解

    C語言進(jìn)階之字符串查找?guī)旌瘮?shù)詳解

    字符串是一種非常重要的數(shù)據(jù)類型,但是C語言不存在顯式的字符串類型,C語言中的字符串都以字符串常量的形式出現(xiàn)或存儲在字符數(shù)組中,下面這篇文章主要給大家介紹了關(guān)于C語言進(jìn)階之字符串查找?guī)旌瘮?shù)的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • C語言實(shí)現(xiàn)牛頓迭代法解方程詳解

    C語言實(shí)現(xiàn)牛頓迭代法解方程詳解

    這篇文章主要介紹了C語言實(shí)現(xiàn)牛頓迭代法解方程詳解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • C++編程中的或||、與&&、非!邏輯運(yùn)算符基本用法整理

    C++編程中的或||、與&&、非!邏輯運(yùn)算符基本用法整理

    這篇文章主要介紹了C++中的或||、與&&、非!邏輯運(yùn)算符基本用法整理,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-01-01
  • FFmpeg實(shí)現(xiàn)變速播放的兩種方法總結(jié)

    FFmpeg實(shí)現(xiàn)變速播放的兩種方法總結(jié)

    這篇文章主要為大家詳細(xì)介紹了FFmpeg中實(shí)現(xiàn)變速播放的兩種方法,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-07-07
  • C語言一看就懂的選擇與循環(huán)語句及函數(shù)介紹

    C語言一看就懂的選擇與循環(huán)語句及函數(shù)介紹

    函數(shù)是一個(gè)功能模塊,它把實(shí)現(xiàn)某個(gè)功能的代碼塊包含起來,并起一個(gè)函數(shù)名,供別人調(diào)用,如printf函數(shù),如system函數(shù)。是程序運(yùn)行當(dāng)中包裝起來的一個(gè)步驟;選擇與循環(huán)是編程中最常用的結(jié)構(gòu),本篇文章用最簡單的文字帶你了解它們
    2022-04-04
  • C語言利用鏈表與文件實(shí)現(xiàn)登錄注冊功能

    C語言利用鏈表與文件實(shí)現(xiàn)登錄注冊功能

    這篇文章主要介紹了C語言利用鏈表與文件實(shí)現(xiàn)登錄注冊功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 深入理解C++內(nèi)鏈接與外鏈接的意義

    深入理解C++內(nèi)鏈接與外鏈接的意義

    鏈接描述了名稱在整個(gè)程序或一個(gè)翻譯單元中如何引用或不引用同一實(shí)體,下面這篇文章主要給大家介紹了關(guān)于C++內(nèi)鏈接與外鏈接意義的理解,需要的朋友可以參考下
    2021-11-11

最新評論