在我的整個職業(yè)生涯里我都在使用C++,而且現(xiàn)在C++依然是我做大多數(shù)項目時的首選編程語言。自然的,當我從2007年開始做ZeroMQ(ZeroMQ項目主頁)時,我選擇用C++來實現(xiàn)。主要的原因有以下幾點:1. 包含數(shù)據(jù)結(jié)構(gòu)和算法的庫(STL)已經(jīng)成為這個語言的一部分了。如果用C,我將要么依賴第三方庫要么不得不自己手動寫一些自1970年來就早已存在的基礎(chǔ)算法。2. C++語言本身在編碼風格的一致性上起到了一些強制作用。比如,有了隱式的this指針參數(shù),這就不允許通過各種不同的方式將指向?qū)ο蟮闹羔樧鲛D(zhuǎn)換,而那種做法在C項目中常常見到(通過各種類型轉(zhuǎn)換)。同樣的還有可以顯式的將成員變量定義為私有的,以及許多其他的語言特性。3. 這個觀點基本上是前一個的子集,但值得我在這里顯式的指出:用C語言實現(xiàn)虛函數(shù)機制比較復雜,而且對于每個類來說會有些許的不同,這使得對代碼的理解和維護都會成為痛苦之源。4. 最后一點是:人人都喜歡析構(gòu)函數(shù),它能在變量離開其作用域時自動得到調(diào)用。如今,5年過去了,我想公開承認:用C++作為ZeroMQ的開發(fā)語言是一個糟糕的選擇,后面我將一一解釋為什么我會這么認為。首先,很重要的一點是ZeroMQ是需要長期連續(xù)不停運行的一個網(wǎng)絡(luò)庫。它應(yīng)該永遠不會出錯,而且永遠不能出現(xiàn)未定義的行為。因此,錯誤處理對于ZeroMQ來說至關(guān)重要,錯誤處理必須是非常明確的而且對錯誤應(yīng)該是零容忍的。C++的異常處理機制卻無法滿足這個要求。C++的異常機制對于確保程序不會失敗是非常有效的——只要將主函數(shù)包裝在try/catch塊中,然后你就可以在一個單獨的位置處理所有的錯誤。然而,當你的目標是確保沒有未定義行為發(fā)生時,噩夢就產(chǎn)生了。C++中引發(fā)異常和處理異常是松耦合的,這使得在 C++中避免錯誤是十分容易的,但卻使得保證程序永遠不會出現(xiàn)未定義行為變得基本不可能。在C語言中,引發(fā)錯誤和處理錯誤的部分是緊耦合的,它們在源代碼中處于同一個位置。這使得我們在錯誤發(fā)生時能很容易理解到底發(fā)生了什么:int rc = fx (); if (rc != 0) handle_error();在C++中,你只是拋出一個異常,到底發(fā)生了什么并不能馬上得知。int rc = fx(); if (rc != 0) throw std::exception();這里的問題就在于你對于誰處理這個異常,以及在哪里處理這個異常是不得而知的。如果你把異常處理代碼也放在同一個函數(shù)中,這么做或多或少還有些明智,盡管這么做會犧牲一點可讀性。try { … int rc = fx(); if (rc != 0) throw std::exception(“Error!”); … catch (std::exception e) { handle_exception(); }但是,考慮一下,如果同一個函數(shù)中拋出了兩個異常時會發(fā)生什么?class exception1 {}; class exception2 {}; try { … if (condition1) throw my_exception1(); … if (condition2) throw my_exception2(); … } catch (my_exception1 e) { handle_exception1(); } catch (my_exception2 e) { handle_exception2(); }對比一下相同的C代碼:… if (condition1) handle_exception1(); … if (condition2) handle_exception2(); …C代碼的可讀性明顯高的多,而且還有一個附加的優(yōu)勢——編譯器會為此產(chǎn)生更高效的代碼。這還沒完呢。再考慮一下這種情況:異常并不是由所拋出異常的函數(shù)來處理。在這種情況下,異常處理可能發(fā)生在任何地方,這取決于這個函數(shù)是在哪調(diào)用的。雖然乍一看我們可以在不同的上下文中處理不同的異常,這似乎很有用,但很快就會變成一場噩夢。當你在解決bug的時候,你會發(fā)現(xiàn)幾乎同樣的錯誤處理代碼在許多地方都出現(xiàn)過。在代碼中增加一個新的函數(shù)調(diào)用可能會引入新的麻煩,不同類型的異常都會涌到調(diào)用函數(shù)這里,而調(diào)用函數(shù)本身并沒有適當進行的處理,這意味著什么?新的bug。如果你依然堅持要杜絕“未定義的行為”,你不得不引入新的異常類型來區(qū)分不同的錯誤模式。然而,增加一個新的異常類型意味著它會涌現(xiàn)在各個不同的地方,那么就需要在所有這些地方都增加一些處理代碼,否則你又會出現(xiàn)“未定義的行為”。到這里你可能會尖叫:這特么算什么異常規(guī)范哪!好吧,問題就在于異常規(guī)范只是以一種更加系統(tǒng)化的方式,以按照指數(shù)規(guī)模增長的異常處理代碼來處理問題的工具,它并沒有解決問題本身。甚至可以說現(xiàn)在情況更加糟糕了,因為你不得不去寫新的異常類型,新的異常處理代碼,以及新的異常規(guī)范。通過上面我描述的問題,我決定使用去掉異常處理機制的C++。這正是ZeroMQ以及Crossroads I/O今天的樣子。但是,很不幸,問題到這并沒有結(jié)束…考慮一下當一個對象初始化失敗的情況。構(gòu)造函數(shù)沒有返回值,因此出錯時只能通過拋出異常來通知出現(xiàn)了錯誤。可是我已經(jīng)決定不使用異常了,那么我不得不這樣做:class foo { public: foo(); int init(); … };當你創(chuàng)建這個類的實例時,構(gòu)造函數(shù)被調(diào)用(不允許失敗),然后你顯式的去調(diào)用init來初始化(init可能會失敗)對象。相比于C語言中的做法,這就顯得過于復雜了。struct foo { … }; int foo_init(struct foo *self);但是以上的例子中,C++版本真正邪惡的地方在于:如果有程序員往構(gòu)造函數(shù)中加入了一些真正的代碼,而不是將構(gòu)造函數(shù)留空時會發(fā)生什么?如果有人真的這么做了,那么就會出現(xiàn)一個新的特殊的對象狀態(tài)——“半初始化狀態(tài)”。這種狀態(tài)是指對象已經(jīng)完成了構(gòu)造(構(gòu)造函數(shù)調(diào)用完成,且沒有失敗),但init函數(shù)還沒有被調(diào)用。我們的對象需要修改(特別是析構(gòu)函數(shù)),這里應(yīng)該以一種方式妥善的處理這種新的狀態(tài),這就意味著又要為每一個方法增加新的條件。看到這里你可能會說:這就是你人為的限制使用異常處理所帶來的后果啊!如果在構(gòu)造函數(shù)中拋出異常,C++運行時庫會負責清理適當?shù)膶ο螅沁@里根本就沒有什么“半初始化狀態(tài)”了!很好,你說的很對,但這根本無關(guān)緊要。如果你使用異常,你就不得不處理所有那些與異常相關(guān)的復雜情況(我前面已經(jīng)描述過了)。而這對于一個面對錯誤時需要非常健壯的基礎(chǔ)組件來說并不是一個合理的選擇。此外,就算初始化不是問題,那析構(gòu)的時候絕對會有問題。
創(chuàng)新互聯(lián)科技有限公司專業(yè)互聯(lián)網(wǎng)基礎(chǔ)服務(wù)商,為您提供服務(wù)器托管,高防服務(wù)器,成都IDC機房托管,成都主機托管等互聯(lián)網(wǎng)服務(wù)。
#include stdio.h
#include stdlib.h
//節(jié)點結(jié)構(gòu)
struct queue{
int num;
struct queue *next;
};
//創(chuàng)建空鏈表
struct queue *initque(void)
{
struct queue *q;
q=(struct queue *)malloc(sizeof(struct queue));
q-next=NULL; //頭結(jié)點啥也沒有
return q;
}
//隊列尾部添加數(shù)據(jù)
void addnum(struct queue * const q,int a)
{
struct queue *n;
struct queue *tmpq=q;//一個會移動的指針
n=(struct queue *)malloc(sizeof(struct queue));//新創(chuàng)建個節(jié)點存儲值
n-num=a;
n-next=NULL;
while(tmpq-next!=NULL)
tmpq=tmpq-next;
tmpq-next=n;//把新建的節(jié)點追加到鏈表末尾
}
//刪除節(jié)點
int delnum(struct queue * const q)
{
int i;
struct queue *current;
struct queue *tmpq=q;
if(tmpq-next!=NULL)
{
current=tmpq-next;//頭結(jié)點的下一結(jié)點,要刪除的節(jié)點
tmpq-next=current-next;//頭結(jié)點跳過要刪除的結(jié)點指向下一結(jié)點
i=current-num;
free(current);
return i;//返回節(jié)點的值
}
return -1;
}
int main(void)
{
struct queue *myq;
myq=initque();
addnum(myq,1);
addnum(myq,3);
addnum(myq,5);
addnum(myq,7);
addnum(myq,9);
printf("%d\n",delnum(myq));
printf("%d\n",delnum(myq));
printf("%d\n",delnum(myq));
printf("%d\n",delnum(myq));
printf("%d\n",delnum(myq));
printf("%d\n",delnum(myq));//隊列空了就返回-1
return 0;
}
PCF就支持C呀!
MQ還提供了系統(tǒng)管理的編程接口,通過該接口用戶可以編寫應(yīng)用程序從而進行自動化的實時監(jiān)控及管理。MQ的系統(tǒng)管理接口有兩種,即Programmable Command Format(可編程命令格式,簡稱PCF)和MQ Administration Interface(MQ管理接口,簡稱MQAI)。
關(guān)于WebSphere MQ 可編程命令格式(PCF)
WebSphere MQ 可編程命令格式(PCF)命令使得管理任務(wù)能編寫到應(yīng)用程序中,在程序中可以創(chuàng)建隊列、進程等對象的定義以及更改對象的屬性等。
PCF定義了命令和回復消息,應(yīng)用程序通過這些命令和回復消息實現(xiàn)和隊列管理器之間的信息交換,PCF 命令和MQSC 命令具有相同的命令集,所有通過MQSC命令能夠?qū)崿F(xiàn)的功能,通過PCF都可以實現(xiàn),因此,通過WebSphere MQ的應(yīng)用程序可以實現(xiàn)對MQ對象的管理包括:隊列管理器,進程定義,隊列和通道等。PCF命令可以被發(fā)送到本地隊列管理器的命令隊列,也可以被發(fā)送到某個遠程隊列管理器的命令隊列,因此,應(yīng)用程序可以通過一個本地隊列管理器集中管理網(wǎng)絡(luò)中的任何本地和遠程管理器。
MQ的遠程管理機制底層就是通過PCF這種方式的,在互相聯(lián)接的系統(tǒng)中的任意一個節(jié)點都可以進行對其他所有節(jié)點的配置和管理,這種情形的典型應(yīng)用就是通過一臺Windows操作系統(tǒng)的機器來管理全網(wǎng)的MQ節(jié)點。由于MQ在Windows XP/NT/2000平臺上提供了圖形界面的管理工具,我們可以把一個節(jié)點設(shè)成管理機,利用管理機可以監(jiān)控和配置網(wǎng)絡(luò)中的任一節(jié)點,監(jiān)測和顯示整個網(wǎng)絡(luò)中任何一個節(jié)點上的服務(wù)器及其各種對象的狀態(tài)和運行情況,從而實現(xiàn)對中間件的集中管理和監(jiān)控。
每一個隊列管理器有一個名為SYSTEM.ADMIN.COMMAND.QUEUE的管理隊列,應(yīng)用程序可以按照PCF命令消息格式封裝的要求,組成PCF消息,并將該PCF命令消息發(fā)送到管理隊列中,同時,每一個隊列管理器也有一個命令服務(wù)器(Command Server),它為管理隊列中的消息提供服務(wù),在我們使用MQ的控制命令strmqcsv啟動命令服務(wù)器之后,它將監(jiān)控管理隊列,一旦該隊列中有PCF消息到達,它將讀取該消息,并解釋執(zhí)行。因此在網(wǎng)絡(luò)中的任何隊列管理器都可以處理PCF消息,通過使用指定的回復隊列,回復消息可以被返回給應(yīng)用程序,應(yīng)用程序可以獲知PCF命令執(zhí)行成功與否。回復隊列由命令消息的消息描述符(MQMD)中的ReplyToQ和ReplyToQMgr兩個字段來指定。
PCF命令和回復消息是使用MQ相應(yīng)的編程接口進行發(fā)送和接收的,以C語言為例,我們只需要使用MQPUT將PCF命令消息發(fā)送到相應(yīng)的管理隊列,使用MQGET將PCF回復消息從相應(yīng)的回復隊列中取出即可。這里的關(guān)鍵就是如何封裝PCF消息。每個MQ指令及其相關(guān)參數(shù)都是一條單獨的命令消息,每個命令消息由PCF頭和若干個參數(shù)結(jié)構(gòu)塊組成,每個參數(shù)結(jié)構(gòu)塊提供了命令的參數(shù)。回復消息的結(jié)構(gòu)與命令消息相同,但是回復消息的個數(shù)根據(jù)不同的情況可能會有多個,例如:如果我們查詢某個隊列管理器下所有本地隊列的屬性,假設(shè)本地隊列有10個,那么我們將得到10個回復消息,PCF頭中的Control字段MQCFC_NOT_LAST和MQCFC_LAST將用于區(qū)分是否為最后一個回復消息。
PCF編程接口支持C,Visual Basic, COBOL, RPG, PL/1和Java等,其中在我們最常用的編程語言中,C和Visual Basic編程在PCF的封裝上相對Java將會略微復雜一些
網(wǎng)上貌似大堆啊,如果不合適,可以找我,根據(jù)你的要求定制或移植
int main(void)
{
int max(int x, int y); //加上聲明
int a,b,c; //多定義了沒用的數(shù)據(jù)
scanf("%d,%d",a,b);
c = max(a,b);
printf("max is %d",c);
}
int max(int x,int y) //加上返回值類型int
{
int z;
if(xy) z=x; //不要逗號
else z=y;
return z;
}
本文題目:mqc語言函數(shù) mqconn函數(shù)
分享網(wǎng)址:http://chinadenli.net/article6/hgojog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、網(wǎng)站策劃、微信小程序、企業(yè)建站、網(wǎng)站內(nèi)鏈、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容