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

C語(yǔ)言多媒體框架GStreamer使用教程深講

 更新時(shí)間:2022年07月19日 14:29:03   作者:dvlinker  
GStreamer 是用來(lái)構(gòu)建流媒體應(yīng)用的開(kāi)源多媒體框架(framework),其目標(biāo)是要簡(jiǎn)化音/視頻應(yīng)用程序的開(kāi)發(fā),已經(jīng)能夠被用來(lái)處理像 MP3、Ogg、MPEG1、MPEG2、AVI、Quicktime 等多種格式的多媒體數(shù)據(jù)

之前參與的萬(wàn)能視頻播放器項(xiàng)目采用了多媒體GStreamer開(kāi)源框架,在最上層業(yè)務(wù)層通過(guò)連接各個(gè)插件形成一個(gè)pipeline來(lái)完成相應(yīng)的業(yè)務(wù)需求。但之前沒(méi)接觸過(guò)GStreamer框架,所以從項(xiàng)目的前期預(yù)研開(kāi)始,就從GStreamer最基本的概念開(kāi)始熟悉,逐步解決項(xiàng)目中遇到的多個(gè)問(wèn)題。本文根據(jù)此次項(xiàng)目實(shí)踐,對(duì)GStreamer多媒體框架做一個(gè)相對(duì)全面的總結(jié)。

1、GStreamer簡(jiǎn)介

GStreamer是GNOME桌面環(huán)境下用來(lái)創(chuàng)建流媒體應(yīng)用的多媒體框架,其基本設(shè)計(jì)思想來(lái)自于俄勒岡(Oregon)研究生學(xué)院有關(guān)視頻管道的創(chuàng)意,同時(shí)也借鑒了DirectShow的設(shè)計(jì)思想。

GStreamer是用c語(yǔ)言實(shí)現(xiàn)的,使用了面向?qū)ο蟮乃季S。GStreamer框架是基于插件和管道的,所有的插件都能夠被鏈接到任意的已經(jīng)定義的數(shù)據(jù)流管道中,數(shù)據(jù)通過(guò)管道機(jī)制進(jìn)行統(tǒng)一交換。GStreamer的很多優(yōu)點(diǎn)來(lái)源于其框架的模塊化,使得新的插件能夠無(wú)縫合并。

GStreamer能夠處理任意類型的數(shù)據(jù)流,其目標(biāo)是要簡(jiǎn)化音/視頻應(yīng)用程序的開(kāi)發(fā),其最顯著的用途是在構(gòu)建音視頻播放器、編輯音視頻文件、音視頻格式轉(zhuǎn)換和流媒體服務(wù)上,GStreamer已經(jīng)能夠被用來(lái)處理像 MP3、Ogg、MPEG1、MPEG2、AVI、Quicktime 等多種格式的多媒體數(shù)據(jù)。

GStreamer核心庫(kù)函數(shù)是一個(gè)處理插件、數(shù)據(jù)流和媒體操作的框架。另外,其還提供了一套API,用于程序員使用其它插件來(lái)編寫他所需要的應(yīng)用程序時(shí)使用。但是,由于追求模塊化和高效率,使得GStreamer在整個(gè)框架上變的復(fù)雜,也同時(shí)因?yàn)閺?fù)雜度的提高,使得開(kāi)發(fā)一個(gè)新的應(yīng)用程序顯得不是那么的簡(jiǎn)單。

2、GStreamer基本概念

2.1、元件(Element)

元件是GStreamer的核心,是具有一定功能的基本單元,可將其描述為一個(gè)具有特定屬性的黑盒子。其在代碼里面的類型是GstElement,可以理解為Gstreamer里面的基類。Gstreamer默認(rèn)安裝了很多有用的元件,按照功能上的差異,element分為以下幾類:

(1)source element 數(shù)據(jù)源元件,只有輸出端,用來(lái)產(chǎn)生供管道消費(fèi)的數(shù)據(jù),例如,音頻捕捉單元,它從聲卡讀取原始音頻數(shù)據(jù),供其它模塊用;

(2)filter(/filter-like) element 中間元件,包括過(guò)濾器、轉(zhuǎn)換器、復(fù)用器、解復(fù)用器、編解碼器等,其既有輸入端又有輸出端,從輸入端獲得相應(yīng)數(shù)據(jù),經(jīng)過(guò)處理之后傳遞給輸出端,有的element可能有一個(gè)source pad多個(gè)sink pads(demux),有的可能有多個(gè)source pads一個(gè)sink pad(mux),有的有一個(gè)source pad一個(gè)sink pad,例如,音頻編碼單元,它從外界獲得音頻數(shù)據(jù)之后,根據(jù)壓縮算法編碼后,給其它模塊使用;

(3)sink elements 接收器元件,只有輸入端,僅有消費(fèi)數(shù)據(jù)的能力,是整條媒體管道的終端,例如,音頻回放單元,負(fù)責(zé)將接收到的數(shù)據(jù)寫到聲卡上;

2.2、箱柜(Bin)

由多個(gè)基本單元組成的一個(gè)高級(jí)的功能單元,是裝載元件的容器,可以通過(guò)改變一個(gè)Bin的狀態(tài)來(lái)改變其內(nèi)部所有元件的狀態(tài),Bin可以發(fā)送總線消息(bus message)給其子集元件。

Bin和pipeline的區(qū)別就是pipeline肯定是bin,但bin不一定是pipeline,bin就像一個(gè)盒子,里面放了什么東西,功能具體是怎么實(shí)現(xiàn)的,用戶可以不關(guān)心,bin是元件的集合,而pipeline更強(qiáng)調(diào)應(yīng)用的可執(zhí)行性。

2.3、管道(Pipeline)

最高等級(jí)的Bin,是一種允許對(duì)所包含的元件進(jìn)行安排(scheduling)的普通容器。頂層(toplevel)箱柜必須為一個(gè)管道,因此每個(gè)GStreamer應(yīng)用程序都至少需要一個(gè)管道。當(dāng)應(yīng)用程序啟動(dòng)后,管道會(huì)自動(dòng)運(yùn)行在后臺(tái)線程中,下面是一個(gè)典型的pipeline示例:

2.4、襯墊(Pad)

不同Elements之間的鏈接點(diǎn),數(shù)據(jù)流在元件之間流動(dòng)就是依靠Pads。Pads有處理特殊數(shù)據(jù)的能力,也就是其支持特定媒體類型的能力,一個(gè)Pads能夠限制數(shù)據(jù)流類型的通過(guò),鏈接成功的條件是,兩個(gè)Pads允許通過(guò)的數(shù)據(jù)類型一致時(shí)才能建立(數(shù)據(jù)類型協(xié)商)。

Pads按照數(shù)據(jù)導(dǎo)向,可分為source pads(element的輸出),sink pads(element 的輸入),按照時(shí)效性可分為,永久型(always)、隨機(jī)型(sometimes)、請(qǐng)求型(on request),三種時(shí)效性的意義顧名思義: 永久型的襯墊一直會(huì)存在,隨機(jī)型的襯墊只在某種特定的條件下才存在(會(huì)隨機(jī)消失的襯墊也屬于隨機(jī)型),請(qǐng)求型的襯墊只在應(yīng)用程序明確發(fā)出請(qǐng)求時(shí)才出現(xiàn)。

Pads通過(guò)GstCaps對(duì)象進(jìn)行描述,一個(gè)GstCaps對(duì)象包括一個(gè)或者多個(gè)GstStructure對(duì)象,一個(gè)GstStructure描述一種媒體類型,其結(jié)構(gòu)中只包含功能集中規(guī)定的固定值。

2.5、能力集(Caps)

Pad的屬性描述,例如:

  SRC template: 'src'
    Availability: Always
    Capabilities:
      audio/x-raw-float
                   rate: [ 8000, 50000 ]
               channels: [ 1, 2 ]
             endianness: 1234
                  width: 32
          buffer-frames: 0
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      audio/x-vorbis

2.6、幽靈pad(ghost pad)

bin本身沒(méi)有pad,所以就沒(méi)有辦法把兩個(gè)bin鏈接起來(lái)。但可以用bin中的一個(gè)元件的pad構(gòu)造一個(gè)代理pad,這樣bin就有一個(gè)代理pad了。這個(gè)pad實(shí)際指向被代理的那個(gè)單元的pad,示例如下:

2.7、Bus

Bus采用自己的線程機(jī)制,負(fù)責(zé)pipeline線程和應(yīng)用程序程序之間的通信。每個(gè)pipeline缺省創(chuàng)建一個(gè)Bus,應(yīng)用程序在總線上設(shè)置一個(gè)類似于對(duì)象的信號(hào)處理的消息處理器,當(dāng)主循環(huán)運(yùn)行的時(shí)候,總線將會(huì)輪詢這個(gè)消息處理器是否有新的消息,當(dāng)消息被采集到后,總線將呼叫相應(yīng)的回調(diào)函數(shù)來(lái)完成相關(guān)操作。

應(yīng)用程序有兩種方法使用Bus,第一種是使用 GLib/Gtk+ main loop及gst_bus_add_watch () or gst_bus_add_signal_watch()事件回調(diào)函數(shù)機(jī)制,第二種是程序通過(guò)gst_bus_peek () /gst_bus_poll ()主動(dòng)檢查Bus中的消息;

2.8、緩沖區(qū)(Buffer)

管道的數(shù)據(jù)流由一組緩沖區(qū)和事件組成,緩沖區(qū)包括實(shí)際的管道數(shù)據(jù),事件包括控制信息,如尋找信息和流的終止信號(hào)。所有這些數(shù)據(jù)流在運(yùn)行的時(shí)候自動(dòng)的流過(guò)管道。

緩沖區(qū)包含了你創(chuàng)建的管道里的數(shù)據(jù)流,通常一個(gè)源元件會(huì)創(chuàng)建一個(gè)新的緩沖區(qū),同時(shí)元件還將會(huì)把緩沖區(qū)的數(shù)據(jù)傳遞給下一個(gè)元件。一個(gè)緩沖區(qū)主要由以下一個(gè)組成:

(1)指向某塊內(nèi)存的指針;

(2)內(nèi)存的大??;

(3)緩沖區(qū)的時(shí)間戳;

(4)一個(gè)引用計(jì)數(shù),指出了緩沖區(qū)所使用的元件數(shù)。沒(méi)有元件可引用的時(shí)候,這個(gè)引用將用于銷毀緩沖區(qū)。

buffer的創(chuàng)建有2種方式,一種是由當(dāng)前的element自己創(chuàng)建,然后把這個(gè)buffer傳遞給下一個(gè)element;另外一種方式就是dwonstream-allocated buffers,就是由下一個(gè)element來(lái)創(chuàng)建要求大小的buffer,并提供buffer操作函數(shù),當(dāng)前element通過(guò)調(diào)用buffer操作函數(shù)將數(shù)據(jù)寫入這個(gè)buffer中完成buffer數(shù)據(jù)傳遞。其區(qū)別在于buffer的創(chuàng)建是在數(shù)據(jù)傳輸?shù)脑炊薳lement創(chuàng)建還是在數(shù)據(jù)接收端element來(lái)創(chuàng)建。

2.9、插件(Plugin)

元件必須封裝在插件中才能被使用,一個(gè)插件是一塊可以加載的代碼,通常被稱為共享對(duì)象文件(shared object file)或動(dòng)態(tài)鏈接庫(kù)(dynamically linked library),一個(gè)插件中可以包含一個(gè)或若干element。

3、GStreamer基本架構(gòu)

GStreamer core、Plugins以及依賴的第三方開(kāi)源庫(kù)的架構(gòu)關(guān)系,如下圖所示,

Gstreamer的組成結(jié)構(gòu)如下圖所示:

4、GStreamer通信機(jī)制

Gstreamer的通信機(jī)制示意圖及解釋如下:

4.1、Message

pipeline用來(lái)主動(dòng)向外報(bào)告自己的運(yùn)行狀態(tài)。這些Message被發(fā)送到一個(gè)消息隊(duì)列,也就是pipeline的Bus,應(yīng)用程序可以從Bus中獲取Message,并作出自定義的反應(yīng)。Message是GST提供的,屬于異步操作;

4.2、Event

pipeline中插件之間進(jìn)行通信的機(jī)制,分為下行事件,上行事件和雙向事件。也可以由應(yīng)用程序直接向某一個(gè)插件發(fā)送事件,但起作用的前提是:該插件定義了該事件的響應(yīng)操作。 通過(guò)事件可以控制整個(gè)pipeline的運(yùn)行狀態(tài)。

下行事件是由source插件向sink插件方向傳輸,例如,

GST_EVENT_EOS (流的終止信號(hào))

GST_EVENT_NEWSEGMENT

上行事件是由sink插件向source插件方向傳輸,用于改變管道中數(shù)據(jù)流的狀態(tài),例如:

GST_EVENT_QOS

GST_EVENT_SEEK(查找)

雙向事件,例如:

GST_EVENT_FLUSH_START

GST_EVENT_FLUSH_STOP

4.3、Signal

應(yīng)用程序控制某一插件的運(yùn)行狀態(tài),signal可以看做Glib對(duì)象的一個(gè)屬性,是由Gobject系統(tǒng)提供的,屬于同步操作,與linux中的系統(tǒng)信號(hào)有差別。通過(guò)信號(hào)可以讓某個(gè)插件做一些對(duì)插件本身變量的操作,比如增加或者刪除一些維護(hù)信息等等。

4.4、Probe

應(yīng)用程序可以通過(guò)探針Probe來(lái)探測(cè)某個(gè)插件的pad中流過(guò)的數(shù)據(jù),比如:在audioconert 插件的src pad 加一個(gè)探針,每當(dāng)有buf到達(dá)時(shí),就調(diào)用callback_have_data(),這里這個(gè)函數(shù)只是打印一下buf的大小,統(tǒng)計(jì)一下buf流過(guò)的個(gè)數(shù);

//main
GstPad *m_pad_concert_src = gst_element_get_static_pad(m_gst_convert, "src");   
gst_pad_add_buffer_probe(m_pad_concert_src, G_CALLBACK(callback_have_data), NULL);
gst_object_unref(m_pad_concert_src);
 
/*******Callback handler when probe date received***********/
static gboolean callback_have_data(GstPad *padsrc, GstBuffer *buffer, gpointer data)
{
    gint    iBufSize = 0;
    gchar*     pBuffer = NULL;
    iBufSize = GST_BUFFER_SIZE(buffer);
    pBuffer = (gchar*)GST_BUFFER_DATA(buffer);
    static gint numBuf = 0;
    g_print("\rBUF %d  Size=%d   ", numBuf++, iBufSize);
    return TRUE;
}

4.5、Quary

應(yīng)用程序可以查詢pipline當(dāng)前的運(yùn)行狀態(tài),比如:以下代碼用來(lái)查詢當(dāng)前播放的位置,和總的播放時(shí)間。

GstFormat m_format = GST_FORMAT_TIME;
gint64 m_position , m_length;
if( gst_element_query_position(pipeline, &m_format,&m_position) &&
  gst_element_query_duration(pipeline, &m_format, &m_length))
{
        g_print("Current: %"GST_TIME_FORMAT"   Total: %" GST_TIME_FORMAT "\r", 
            GST_TIME_ARGS(m_position),GST_TIME_ARGS(m_length));
}

5、GStreamer元件狀態(tài)

一個(gè)元件在被創(chuàng)建后,它不會(huì)執(zhí)行任何操作,通過(guò)改變?cè)臓顟B(tài),才能使它做某些事情。元件有四種狀態(tài),每種狀態(tài)都有其特定的意義,具體如下:

GST_STATE_NULL 默認(rèn)狀態(tài):沒(méi)有分配任何資源,沒(méi)有載入插件,不能處理數(shù)據(jù);

GST_STATE_READY 預(yù)備狀態(tài):分配或載入所有與流無(wú)關(guān)的資源(非硬件資源),所有數(shù)據(jù)流的位置信息應(yīng)該自動(dòng)置0,如果數(shù)據(jù)流先前被打開(kāi)過(guò),它應(yīng)該被關(guān)閉,并且其位置信息、特性信息應(yīng)該被重新置為初始狀態(tài);

GST_STATE_PAUSED 暫停狀態(tài):準(zhǔn)備好全部資源,接受數(shù)據(jù)流,只是sink element暫停,收到數(shù)據(jù)不處理,只是block;

GST_STATE_PLAYING 播放狀態(tài):準(zhǔn)備好全部資源,接受并處理數(shù)據(jù)流;其實(shí)這個(gè)狀態(tài)除了當(dāng)前運(yùn)行時(shí)鐘外,其它與PAUSED狀態(tài)一樣,可以通過(guò)gst_element_set_state()來(lái)改變一個(gè)元件的狀態(tài),當(dāng)元件處于GST_STATE_PLAYING狀態(tài),管道會(huì)開(kāi)始自動(dòng)處理數(shù)據(jù)。

6、GStreamer中的幾個(gè)關(guān)鍵概念

6.1、識(shí)別流的MIME類型

元件通過(guò)caps來(lái)描述其能處理的媒體格式,元件之間交互數(shù)據(jù)流通過(guò)caps協(xié)商,caps是一個(gè)mime類型或者一些特性集的組合。

一個(gè)加載進(jìn)系統(tǒng)的元件必須提供其源襯墊和接收襯墊支持的mime類型。通過(guò)Gstreamer注冊(cè)中心可以知道目前注冊(cè)的不同的元件,以及他們所期望得到的與他們能夠產(chǎn)生的媒體類型,下圖顯示了管道中每個(gè)Pads所處理的MIME類型。

6.2、媒體流類型檢測(cè)(typefind)

通常當(dāng)加載一個(gè)新的媒體流時(shí),媒體的類型并不明了。這意味著選擇一條管道來(lái)對(duì)媒體流進(jìn)行解碼之前,首先需要檢測(cè)媒體流的類型。 GStreamer 使用了類型檢測(cè) (typefinding) 來(lái)達(dá)到此目的。類型檢測(cè)是構(gòu)建管道所必經(jīng)的步驟。

首先它會(huì)一直讀取數(shù)據(jù)流,在此期間,它會(huì)把數(shù)據(jù)提供給所有的實(shí)現(xiàn)了類型檢測(cè)器 (typefinder) 的插件,當(dāng)其中任何一個(gè)類型檢測(cè)器識(shí)別出數(shù)據(jù)流,這個(gè)類型檢測(cè)器元件將會(huì)發(fā)送一個(gè)信號(hào),并開(kāi)始像一個(gè)關(guān)卡 (passthrough)模塊一樣工作。如果數(shù)據(jù)流的類型沒(méi)有被任何類型檢測(cè)器識(shí)別出來(lái),管道會(huì)發(fā)送一個(gè)錯(cuò)誤信息,并終止所有正在處理該數(shù)據(jù)流的動(dòng)作。一旦類型檢測(cè)元件找到一個(gè)類型,應(yīng)用程序?qū)?huì)使用該元件作為管道的一部分來(lái)解碼媒體流。

6.3、數(shù)據(jù)探測(cè)

探測(cè)是襯墊監(jiān)聽(tīng)器的形象比喻,從技術(shù)上,探針僅僅是一個(gè)可以依附于襯墊的回調(diào)信號(hào)。這些信號(hào)默認(rèn)是沒(méi)有被發(fā)射(fired)的(不然的話會(huì)降低性能),但是可以通過(guò)附加探針調(diào)用gst_pad_add_data_probe() 或類似的函數(shù)被激活,這些函數(shù)附加了信號(hào)處理器,并激活實(shí)際信號(hào)的發(fā)射。

同樣地,你可以用 gst_pad_remove_data_probe () 或相關(guān)函數(shù)來(lái)刪除信號(hào)處理器,也可以只是監(jiān)聽(tīng)時(shí)間或緩沖區(qū)。 探針在管道的線程context運(yùn)行,所以回調(diào)不應(yīng)該阻塞,而且通常不能有異常的阻塞,否則會(huì)降低管道的性能,如果出現(xiàn)這樣的缺陷,會(huì)導(dǎo)致死鎖甚至崩潰。

6.4、插件加載流程

如下圖所示,基于插件的程序,其工作原理本質(zhì)上都是通過(guò)讀取動(dòng)態(tài)庫(kù)實(shí)現(xiàn)的,只需要每個(gè)動(dòng)態(tài)庫(kù)中實(shí)現(xiàn)某一個(gè)特定的接口就可以了,比如XX_init等,這里就是plugin_init。里面會(huì)有個(gè)像注冊(cè)表一樣的數(shù)據(jù)結(jié)構(gòu)會(huì)存儲(chǔ)所有的插件的信息。

7、GStreamer開(kāi)發(fā)示例-MP3文件播放器

利用GStreamer框架提供的組件,來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的MP3播放器。數(shù)據(jù)源元件負(fù)責(zé)從磁盤上讀取數(shù)據(jù),過(guò)濾器元件負(fù)責(zé)對(duì)數(shù)據(jù)進(jìn)行解碼,而接受器元件則負(fù)責(zé)將解碼后的數(shù)據(jù)寫入聲卡,示例代碼和注釋如下:

#include <gst/gst.h>
#include <glib.h>
//定義消息處理函數(shù),
static gboolean bus_call(GstBus *bus,GstMessage *msg,gpointer data)
{
    GMainLoop *loop = (GMainLoop *) data;//主循環(huán)的指針,接受EOS消息時(shí)退出
    switch (GST_MESSAGE_TYPE(msg))
    {
        case GST_MESSAGE_EOS:
            g_print("End of stream\n");
            g_main_loop_quit(loop);
            break;
        case GST_MESSAGE_ERROR:
        {
            gchar *debug;
            GError *error;
            gst_message_parse_error(msg,&error,&debug);
            g_free(debug);
            g_printerr("ERROR:%s\n",error->message);
            g_error_free(error);
            g_main_loop_quit(loop);
            break;
        }
        default:
             break;
    }
    return TRUE;
}
int main(int argc,char *argv[])
{
    GMainLoop *loop;
    GstElement *pipeline,*source,*decoder,*sink;//定義組件
    GstBus *bus;
    gst_init(&argc,&argv); //初始化gstreamer
    loop = g_main_loop_new(NULL,FALSE);//創(chuàng)建主循環(huán),在執(zhí)行 g_main_loop_run后正式開(kāi)始循環(huán)
    if(argc != 2)
    {
        g_printerr("Usage:%s <mp3 filename>\n",argv[0]);
        return -1;
    }
    //創(chuàng)建管道和元件
    pipeline = gst_pipeline_new("audio-player"); //管道用來(lái)容納元件
    source = gst_element_factory_make("filesrc","file-source");//數(shù)據(jù)源元件
    decoder = gst_element_factory_make("mad","mad-decoder");//過(guò)濾器元件
    sink = gst_element_factory_make("autoaudiosink","audio-output");//接收器元件
    if(!pipeline||!source||!decoder||!sink){
        g_printerr("One element could not be created.Exiting.\n");
        return -1;
    }
    //設(shè)置 source的location 參數(shù),即文件地址.
    g_object_set(G_OBJECT(source),"location",argv[1],NULL);
    //得到管道的消息總線
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    //添加消息監(jiān)視器
    gst_bus_add_watch(bus,bus_call,loop);
    gst_object_unref(bus);
    //把元件添加到管道中。管道是一個(gè)特殊的組件,可以更好的讓數(shù)據(jù)流動(dòng)
    gst_bin_add_many(GST_BIN(pipeline),source,decoder,sink,NULL);
    //通過(guò)襯墊依次連接元件
    gst_element_link_many(source,decoder,sink,NULL);
    //啟動(dòng)管道,開(kāi)始播放
    gst_element_set_state(pipeline,GST_STATE_PLAYING);
    g_print("Running\n");
    //開(kāi)始循環(huán)
    g_main_loop_run(loop);
    g_print("Returned,stopping playback\n");
    //終止管道,釋放資源
    gst_element_set_state(pipeline,GST_STATE_NULL);
    gst_object_unref(GST_OBJECT(pipeline));
    return 0;
}

編譯運(yùn)行

gcc-Wall$(pkg-config--cflags--libsgstreamer-0.10)-gtest2.c-otest2

./test2/home/phinecos/test.mp3

8、最后

本文總結(jié)了多媒體框架GStreamer一些基本概念及流程,希望能給使用GStreamer開(kāi)源庫(kù)的朋友提供一個(gè)借鑒或參考。

到此這篇關(guān)于C語(yǔ)言多媒體框架GStreamer使用教程深講的文章就介紹到這了,更多相關(guān)C語(yǔ)言GStreamer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)找出二叉樹(shù)中某個(gè)值的所有路徑的方法

    C語(yǔ)言實(shí)現(xiàn)找出二叉樹(shù)中某個(gè)值的所有路徑的方法

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)找出二叉樹(shù)中某個(gè)值的所有路徑的方法,針對(duì)數(shù)據(jù)結(jié)構(gòu)中二叉樹(shù)的實(shí)用操作技巧,需要的朋友可以參考下
    2014-09-09
  • C語(yǔ)言模擬實(shí)現(xiàn)通訊錄程序過(guò)程

    C語(yǔ)言模擬實(shí)現(xiàn)通訊錄程序過(guò)程

    這篇文章主要介紹了C語(yǔ)言模擬實(shí)現(xiàn)通訊錄程序過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-02-02
  • c++快速排序詳解

    c++快速排序詳解

    快速排序總體思想:先找到一個(gè)樞軸,讓他作為分水嶺。通過(guò)一趟排序?qū)⒋判虻挠涗浄指畛瑟?dú)立的兩部分,前面一部分都比樞軸小,后面一部分逗比樞軸大,然后又分別對(duì)這兩部分記錄繼續(xù)進(jìn)行遞歸的排序,達(dá)到整個(gè)序列有序的目的。
    2017-05-05
  • 二分法求多項(xiàng)式在-10 10間值的實(shí)現(xiàn)代碼

    二分法求多項(xiàng)式在-10 10間值的實(shí)現(xiàn)代碼

    以下實(shí)例是介紹了二分法求多項(xiàng)式在-10 10間值的實(shí)現(xiàn)代碼。需要的朋友參考下
    2013-05-05
  • OpenCV實(shí)現(xiàn)更改圖片顏色功能

    OpenCV實(shí)現(xiàn)更改圖片顏色功能

    這篇文章主要為大家詳細(xì)介紹了如何利用OpenCV實(shí)現(xiàn)更改圖片顏色的功能,文中代碼介紹詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C++實(shí)現(xiàn)冒泡排序(BubbleSort)

    C++實(shí)現(xiàn)冒泡排序(BubbleSort)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)冒泡排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 用C語(yǔ)言進(jìn)行最基本的socket編程

    用C語(yǔ)言進(jìn)行最基本的socket編程

    這篇文章主要介紹了C語(yǔ)言下socket編程的基本知識(shí)講解,包括最基本的客戶端發(fā)送及服務(wù)器端接受數(shù)據(jù)的實(shí)現(xiàn),需要的朋友可以參考下
    2015-11-11
  • C語(yǔ)言實(shí)現(xiàn)密碼本

    C語(yǔ)言實(shí)現(xiàn)密碼本

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)密碼本,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)深入探索順序表

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)深入探索順序表

    順序表,全名順序存儲(chǔ)結(jié)構(gòu),是線性表的一種,線性表用于存儲(chǔ)邏輯關(guān)系為“一對(duì)一”的數(shù)據(jù),順序表自然也不例外,不僅如此,順序表對(duì)數(shù)據(jù)的物理存儲(chǔ)結(jié)構(gòu)也有要求,跟隨下文來(lái)具體了解吧
    2022-03-03
  • C語(yǔ)言 pthread_create() 函數(shù)講解

    C語(yǔ)言 pthread_create() 函數(shù)講解

    這篇文章主要介紹了C語(yǔ)言 pthread_create() 函數(shù)講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論