導航:首頁 > 源碼編譯 > pidc編譯器

pidc編譯器

發布時間:2023-09-09 21:00:06

『壹』 PLC電控是什麼東西如何解釋

1、PLC即可編程控制器(Programmable logic Controller,是指以計算機技術為基礎的新型工業控制裝置。在1987年國際電工委員會(International Electrical Committee)頒布的PLC標准草案中對PLC做了如下定義:

「PLC是一種專門為在工業環境下應用而設計的數字運算操作的電子裝置。它採用可以編製程序的存儲器,用來在其內部存儲執行邏輯運算、順序運算、計時、計數和算術運算等操作的指令,並能通過數字式或模擬式的輸入和輸出,控制各種類型的機械或生產過程。PLC及其有關的外圍設備都應該按易於與工業控制系統形成一個整體,易於擴展其功能的原則而設計。」

PLC的特點

2.1可靠性高,抗干擾能力強
高可靠性是電氣控制設備的關鍵性能。PLC由於採用現代大規模集成電路技術,採用嚴格的生產工藝製造,內部電路採取了先進的抗干擾技術,具有很高的可靠性。例如三菱公司生產的F系列PLC平均無故障時間高達30萬小時。一些使用冗餘CPU的PLC的平均無故障工作時間則更長。從PLC的機外電路來說,使用PLC構成控制系統,和同等規模的繼電接觸器系統相比,電氣接線及開關接點已減少到數百甚至數千分之一,故障也就大大降低。此外,PLC帶有硬體故障自我檢測功能,出現故障時可及時發出警報信息。在應用軟體中,應用者還可以編入外圍器件的故障自診斷程序,使系統中除PLC以外的電路及設備也獲得故障自診斷保護。這樣,整個系統具有極高的可靠性也就不奇怪了。

2.2配套齊全,功能完善,適用性強
PLC發展到今天,已經形成了大、中、小各種規模的系列化產品。可以用於各種規模的工業控制場合。除了邏輯處理功能以外,現代PLC大多具有完善的數據運算能力,可用於各種數字控制領域。近年來PLC的功能單元大量涌現,使PLC滲透到了位置控制、溫度控制、CNC等各種工業控制中。加上PLC通信能力的增強及人機界面技術的發展,使用PLC組成各種控制系統變得非常容易。

2.3易學易用,深受工程技術人員歡迎
PLC作為通用工業控制計算機,是面向工礦企業的工控設備。它介面容易,編程語言易於為工程技術人員接受。梯形圖語言的圖形符號與表達方式和繼電器電路圖相當接近,只用PLC的少量開關量邏輯控制指令就可以方便地實現繼電器電路的功能。為不熟悉電子電路、不懂計算機原理和匯編語言的人使用計算機從事工業控制打開了方便之門。

2.4系統的設計、建造工作量小,維護方便,容易改造
PLC用存儲邏輯代替接線邏輯,大大減少了控制設備外部的接線,使控制系統設計及建造的周期大為縮短,同時維護也變得容易起來。更重要的是使同一設備經過改變程序改變生產過程成為可能。這很適合多品種、小批量的生產場合。

2.5體積小,重量輕,能耗低
以超小型PLC為例,新近出產的品種底部尺寸小於100mm,重量小於150g,功耗僅數瓦。由於體積小很容易裝入機械內部,是實現機電一體化的理想控制設備。

3. PLC的應用領域
目前,PLC在國內外已廣泛應用於鋼鐵、石油、化工、電力、建材、機械製造、汽車、輕紡、交通運輸、環保及文化娛樂等各個行業,使用情況大致可歸納為如下幾類。

3.1開關量的邏輯控制
這是PLC最基本、最廣泛的應用領域,它取代傳統的繼電器電路,實現邏輯控制、順序控制,既可用於單台設備的控制,也可用於多機群控及自動化流水線。如注塑機、印刷機、訂書機械、組合機床、磨床、包裝生產線、電鍍流水線等。

3.2模擬量控制
在工業生產過程當中,有許多連續變化的量,如溫度、壓力、流量、液位和速度等都是模擬量。為了使可編程式控制制器處理模擬量,必須實現模擬量(Analog)和數字量(Digital)之間的A/D轉換及D/A轉換。PLC廠家都生產配套的A/D和D/A轉換模塊,使可編程式控制制器用於模擬量控制。

3.3運動控制
PLC可以用於圓周運動或直線運動的控制。從控制機構配置來說,早期直接用於開關量I/O模塊連接位置感測器和執行機構,現在一般使用專用的運動控制模塊。如可驅動步進電機或伺服電機的單軸或多軸位置控制模塊。世界上各主要PLC廠家的產品幾乎都有運動控制功能,廣泛用於各種機械、機床、機器人、電梯等場合。

3.4過程式控制制
過程式控制制是指對溫度、壓力、流量等模擬量的閉環控制。作為工業控制計算機,PLC能編制各種各樣的控制演算法程序,完成閉環控制。PID調節是一般閉環控制系統中用得較多的調節方法。大中型PLC都有PID模塊,目前許多小型PLC也具有此功能模塊。PID處理一般是運行專用的PID子程序。過程式控制制在冶金、化工、熱處理、鍋爐控制等場合有非常廣泛的應用。

3.5數據處理
現代PLC具有數學運算(含矩陣運算、函數運算、邏輯運算)、數據傳送、數據轉換、排序、查表、位操作等功能,可以完成數據的採集、分析及處理。這些數據可以與存儲在存儲器中的參考值比較,完成一定的控制操作,也可以利用通信功能傳送到別的智能裝置,或將它們列印製表。數據處理一般用於大型控制系統,如無人控制的柔性製造系統;也可用於過程式控制制系統,如造紙、冶金、食品工業中的一些大型控制系統。

3.6通信及聯網
PLC通信含PLC間的通信及PLC與其它智能設備間的通信。隨著計算機控制的發展,工廠自動化網路發展得很快,各PLC廠商都十分重視PLC的通信功能,紛紛推出各自的網路系統。新近生產的PLC都具有通信介面,通信非常方便。

4. PLC的國內外狀況

世界上公認的第一台PLC是1969年美國數字設備公司(DEC)研製的。限於當時的元器件條件及計算機發展水平,早期的PLC主要由分立元件和中小規模集成電路組成,可以完成簡單的邏輯控制及定時、計數功能。20世紀70年代初出現了微處理器。人們很快將其引入可編程式控制制器,使PLC增加了運算、數據傳送及處理等功能,完成了真正具有計算機特徵的工業控制裝置。為了方便熟悉繼電器、接觸器系統的工程技術人員使用,可編程式控制制器採用和繼電器電路圖類似的梯形圖作為主要編程語言,並將參加運算及處理的計算機存儲元件都以繼電器命名。此時的PLC為微機技術和繼電器常規控制概念相結合的產物。

20世紀70年代中末期,可編程式控制制器進入實用化發展階段,計算機技術已全面引入可編程式控制制器中,使其功能發生了飛躍。更高的運算速度、超小型體積、更可靠的工業抗干擾設計、模擬量運算、PID功能及極高的性價比奠定了它在現代工業中的地位。20世紀80年代初,可編程式控制制器在先進工業國家中已獲得廣泛應用。這個時期可編程式控制制器發展的特點是大規模、高速度、高性能、產品系列化。這個階段的另一個特點是世界上生產可編程式控制制器的國家日益增多,產量日益上升。這標志著可編程式控制制器已步入成熟階段。

20世紀末期,可編程式控制制器的發展特點是更加適應於現代工業的需要。從控制規模上來說,這個時期發展了大型機和超小型機;從控制能力上來說,誕生了各種各樣的特殊功能單元,用於壓力、溫度、轉速、位移等各式各樣的控制場合;從產品的配套能力來說,生產了各種人機界面單元、通信單元,使應用可編程式控制制器的工業控制設備的配套更加容易。目前,可編程式控制制器在機械製造、石油化工、冶金鋼鐵、汽車、輕工業等領域的應用都得到了長足的發展。

我國可編程式控制制器的引進、應用、研製、生產是伴隨著改革開放開始的。最初是在引進設備中大量使用了可編程式控制制器。接下來在各種企業的生產設備及產品中不斷擴大了PLC的應用。目前,我國自己已可以生產中小型可編程式控制制器。上海東屋電氣有限公司生產的CF系列、杭州機床電器廠生產的DKK及D系列、大連組合機床研究所生產的S系列、蘇州電子計算機廠生產的YZ系列等多種產品已具備了一定的規模並在工業產品中獲得了應用。此外,無錫華光公司、上海鄉島公司等中外合資企業也是我國比較著名的PLC生產廠家。可以預期,隨著我國現代化進程的深入,PLC在我國將有更廣闊的應用天地。

5. PLC未來展望
21世紀,PLC會有更大的發展。從技術上看,計算機技術的新成果會更多地應用於可編程式控制制器的設計和製造上,會有運算速度更快、存儲容量更大、智能更強的品種出現;從產品規模上看,會進一步向超小型及超大型方向發展;從產品的配套性上看,產品的品種會更豐富、規格更齊全,完美的人機界面、完備的通信設備會更好地適應各種工業控制場合的需求;從市場上看,各國各自生產多品種產品的情況會隨著國際競爭的加劇而打破,會出現少數幾個品牌壟斷國際市場的局面,會出現國際通用的編程語言;從網路的發展情況來看,可編程式控制制器和其它工業控制計算機組網構成大型的控制系統是可編程式控制制器技術的發展方向。目前的計算機集散控制系統DCS(Distributed

Control

System)中已有大量的可編程式控制制器應用。伴隨著計算機網路的發展,可編程式控制制器作為自動化控制網路和國際通用網路的重要組成部分,將在工業及工業以外的眾多領域發揮越來越大的作用。

1 PLC基礎知識

1.1 PLC的發展歷程

在工業生產過程中,大量的開關量順序控制,它按照邏輯條件進行順序動作,並按照邏輯關系進行連鎖保護動作的控制,及大量離散量的數據採集。傳統上,這些功能是通過氣動或電氣控制系統來實現的。1968年美國GM(通用汽車)公司提出取代繼電氣控制裝置的要求,第二年,美國數字公司研製出了基於集成電路和電子技術的控制裝置,首次採用程序化的手段應用於電氣控制,這就是第一代可編程序控制器,稱Programmable

Controller(PC)。

個人計算機(簡稱PC)發展起來後,為了方便,也為了反映可編程式控制制器的功能特點,可編程序控制器定名為Programmable

Logic Controller(PLC)。

上世紀80年代至90年代中期,是PLC發展最快的時期,年增長率一直保持為30~40%。在這時期,PLC在處理模擬量能力、數字運算能力、人機介面能力和網路能力得到大幅度提高,PLC逐漸進入過程式控制制領域,在某些應用上取代了在過程式控制制領域處於統治地位的DCS系統。

PLC具有通用性強、使用方便、適應面廣、可靠性高、抗干擾能力強、編程簡單等特點。PLC在工業自動化控制特別是順序控制中的地位,在可預見的將來,是無法取代的。

1.2 PLC的構成

從結構上分,PLC分為固定式和組合式(模塊式)兩種。固定式PLC包括CPU板、I/O板、顯示面板、內存塊、電源等,這些元素組合成一個不可拆卸的整體。模塊式PLC包括CPU模塊、I/O模塊、內存、電源模塊、底板或機架,這些模塊可以按照一定規則組合配置。

1.3 CPU的構成

CPU是PLC的核心,起神經中樞的作用,每套PLC至少有一個CPU,它按PLC的系統程序賦予的功能接收並存貯用戶程序和數據,用掃描的方式採集由現場輸入裝置送來的狀態或數據,並存入規定的寄存器中,同時,診斷電源和PLC內部電路的工作狀態和編程過程中的語法錯誤等。進入運行後,從用戶程序存貯器中逐條讀取指令,經分析後再按指令規定的任務產生相應的控制信號,去指揮有關的控制電路。

CPU主要由運算器、控制器、寄存器及實現它們之間聯系的數據、控制及狀態匯流排構成,CPU單元還包括外圍晶元、匯流排介面及有關電路。內存主要用於存儲程序及數據,是PLC不可缺少的組成單元。

在使用者看來,不必要詳細分析CPU的內部電路,但對各部分的工作機制還是應有足夠的理解。CPU的控制器控制CPU工作,由它讀取指令、解釋指令及執行指令。但工作節奏由震盪信號控制。運算器用於進行數字或邏輯運算,在控制器指揮下工作。寄存器參與運算,並存儲運算的中間結果,它也是在控制器指揮下工作。

CPU速度和內存容量是PLC的重要參數,它們決定著PLC的工作速度,IO數量及軟體容量等,因此限制著控制規模。

1.4 I/O模塊

PLC與電氣迴路的介面,是通過輸入輸出部分(I/O)完成的。I/O模塊集成了PLC的I/O電路,其輸入暫存器反映輸入信號狀態,輸出點反映輸出鎖存器狀態。輸入模塊將電信號變換成數字信號進入PLC系統,輸出模塊相反。I/O分為開關量輸入(DI),開關量輸出(DO),模擬量輸入(AI),模擬量輸出(AO)等模塊。

常用的I/O分類如下:

開關量:按電壓水平分,有220VAC、110VAC、24VDC,按隔離方式分,有繼電器隔離和晶體管隔離。

模擬量:按信號類型分,有電流型(4-20mA,0-20mA)、電壓型(0-10V,0-5V,-10-10V)等,按精度分,有12bit,14bit,16bit等。

除了上述通用IO外,還有特殊IO模塊,如熱電阻、熱電偶、脈沖等模塊。

按I/O點數確定模塊規格及數量,I/O模塊可多可少,但其最大數受CPU所能管理的基本配置的能力,即受最大的底板或機架槽數限制。

1.5 電源模塊

PLC電源用於為PLC各模塊的集成電路提供工作電源。同時,有的還為輸入電路提供24V的工作電源。電源輸入類型有:交流電源(220VAC或110VAC),直流電源(常用的為24VDC)。

1.6 底板或機架

大多數模塊式PLC使用底板或機架,其作用是:電氣上,實現各模塊間的聯系,使CPU能訪問底板上的所有模塊,機械上,實現各模塊間的連接,使各模塊構成一個整體。

1.7 PLC系統的其它設備

1.7.1

編程設備:編程器是PLC開發應用、監測運行、檢查維護不可缺少的器件,用於編程、對系統作一些設定、監控PLC及PLC所控制的系統的工作狀況,但它不直接參與現場控制運行。小編程器PLC一般有手持型編程器,目前一般由計算機(運行編程軟體)充當編程器。也就是我們系統的上位機。

1.7.2 人機界面:最簡單的人機界面是指示燈和按鈕,目前液晶屏(或觸摸屏)式的一體式操作員終端應用越來越廣泛,由計算機(運行組態軟體)充當人機界面非常普及。

1.8 PLC的通信聯網

依靠先進的工業網路技術可以迅速有效地收集、傳送生產和管理數據。因此,網路在自動化系統集成工程中的重要性越來越顯著,甚至有人提出"網路就是控制器"的觀點說法。

PLC具有通信聯網的功能,它使PLC與PLC

之間、PLC與上位計算機以及其他智能設備之間能夠交換信息,形成一個統一的整體,實現分散集中控制。多數PLC具有RS-232介面,還有一些內置有支持各自通信協議的介面。PLC的通信現在主要採用通過多點介面(MPI)的數據通訊、PROFIBUS

或工業乙太網進行聯網。

2 PLC控制系統的設計基本原則
2.1 最大限度的滿足被控對象的控制要求。
2.2 在滿足控制要求的前提下,力求使控制系統簡單、經濟、使用和維護方便。
2.3 保證控制系統安全可靠。
2.4 考慮到生產的發展和工藝的改進在選擇PLC容量時應適當留有餘量。
3 PLC軟體系統及常用編程語言

3.1 PLC軟體系統由系統程序和用戶程序兩部分組成。系統程序包括監控程序、編譯程序、診斷程序等,主要用於管理全機、將程序語言翻譯成機器語言,診斷機器故障。系統軟體由PLC廠家提供並已固化在EPROM中,不能直接存取和干預。用戶程序是用戶根據現場控制要求,用PLC的程序語言編制的應用程序(也就是邏輯控制)用來實現各種控制。STEP7是用於SIMATIC可編程邏輯控制器組態和編程的標准軟體包,也就是用戶程序,我們就是使用STEP7來進行硬體組態和邏輯程序編制,以及邏輯程序執行結果的在線監視。

3.2 PLC提供的編程語言

3.2.1 標准語言梯形圖語言也是我們最常用的一種語言,它有以下特點

3.2.1.1 它是一種圖形語言,沿用傳統控制圖中的繼電器觸點、線圈、串聯等術語和一些圖形符號構成,左右的豎線稱為左右母線。

3.2.1.2 梯形圖中接點(觸點)只有常開和常閉,接點可以是PLC輸入點接的開關也可以是PLC內部繼電器的接點或內部寄存器、計數器等的狀態。

3.2.1.3 梯形圖中的接點可以任意串、並聯,但線圈只能並聯不能串聯。

3.2.1.4 內部繼電器、計數器、寄存器等均不能直接控制外部負載,只能做中間結果供CPU內部使用。

3.2.1.5 PLC是按循環掃描事件,沿梯形圖先後順序執行,在同一掃描周期中的結果留在輸出狀態暫存器中所以輸出點的值在用戶程序中可以當做條件使用。

3.2.2 語句表語言,類似於匯編語言。

3.2.3 邏輯功能圖語言,沿用半導體邏輯框圖來表達,一般一個運算框表示一個功能左邊畫輸入、右邊畫輸出。

4 STEP7程序的使用

4.1 創建一個項目結構,項目就象一個文件夾,所有數據都以分層的結構存在於其中,任何時候你都可以使用。在創建一個項目之後,所有其他任務都在這個項目下執行。

4.2 組態一個站,組態一個站就是指定你要使用的可編程式控制制器,例如S7300、S7400等。

4.3 組態硬體,組態硬體就是在組態表中指定你的控制方案所要使用的模板以及在用戶程序中以什麼樣的地址來訪問這些模板,地址一般不用修改由程序自動生成。模板的特性也可以用參數進行賦值。

4.4 組態網路和通訊連接,通訊的基礎是預先組態網路,也就是要創建一個滿足你的控制方案的子網,設置網路特性、設置網路連接特性以及任何聯網的站所需要的連接。網路地址也是程序自動生成如果沒有更改經驗一定不要修改。

4.5 定義符號,可以在符號表中定義局部或共享符號,在你的用戶程序中用這些更具描述性的符號名替代絕對地址。符號的命名一般用字母編寫不超過8個位元組,最好不要使用很長的漢字進行描述,否則對程序的執行有很大的影響。

4.6 創建程序,用梯形圖編程語言創建一個與模板相連結或與模板無關的程序並存儲。創建程序是我們控制工程的重要工作之一,一般可以採用線形編程(基於一個塊內,OB1)、分布編程(編寫功能塊FB,OB1組織調用)、結構化編程(編寫通用塊)。我們最常採用的是結構化編程和分布編程配合使用,很少採用線形編程。

4.7 下載程序到可編程式控制制器,完成所有的組態、參數賦值和編程任務之後,可以下載整個用戶程序到可編程式控制制器。在下載程序時可編程式控制制器必須在允許下載的工作模式下(STOP或RUN-P),

RUN-P模式表示,這個程序將一次下載一個塊,如果重寫一個舊的CPU程序就可能出現沖突,所以一般在下載前將CPU切換到STOP模式。

5 WINCC程序的使用

5.1 簡介,WINCC是在生產和過程自動化中解決可視化和控制任務的工業技術中性系統。具有控制自動化過程的強大功能,是基於個人計算機的操作監視系統,它很容易結合標準的和用戶的程序建立人機界面精確的滿足生產實際要求。WINCC有兩個版本RC版(具有組態和開發環境)、RT版(只有運行環境),我們一般使用的是RC版。

5.2 WINCC簡單使用步驟

5.2.1 變數管理,首先確定通訊方式安裝驅動程序,然後定義內部變數和外部變數,外部變數是受你買的WINCC軟體授許可權制的最大授權64K位元組,內部變數沒有限制。

5.2.2 畫面生成,進入圖形編輯器,圖形編輯器是一種用於創建過程畫面的面向矢量的作圖程序。也可以使用包含在對象和樣式庫中的眾多的圖形對象來創建復雜的過程畫面。可以通過動作編程將動態添加到單個圖形對象上。

5.2.3 報警記錄設置,報警記錄提供了顯示和操作選項來獲取和歸檔結果。可以任意地選擇消息塊、消息級別、消息類型、消息顯示以及報表。為了在運行中顯示消息,可以使用包含在圖形編輯器中的對象庫中的報警控制項。

5.2.4 變數記錄,變數記錄是用來從運行過程中採集數據並准備將它們顯示和歸檔。

5.2.5 報表組態,報表組態是通過報表編輯器來實現的。是為消息、操作、歸檔內容和當前或已歸檔的數據定時器或事件控制文檔的集成的報表系統,可以自由選擇用戶報表的形式。

5.2.6 全局腳本的應用,全局腳本就是C語言函數和動作的通稱,根據不同的類型腳本被用於給對象組態動作並通過系統內部C語言編譯器來處理。全局腳本動作用於過程執行的運行中。一個觸發可以開始這些動作的執行。

5.2.7 用戶管理器設置,用戶管理器用於分配和控制用戶的單個組態和運行系統編輯器的訪問許可權。每建立一個用戶,就設置了WINCC功能的訪問權利並獨立的分配給此用戶。至多可分配999個不同的授權。

5.2.8 交叉表索引,交叉索引用於為對象尋找和顯示所有使用處,例如變數、畫面和函數等。使用「鏈接」功能可以改變變數名稱而不會導致組態不一致。

參考文獻
[1] 林小峰.可編程式控制制器原理及應用.北京:高等教育出版社,1994
[2] 田瑞庭.可編程式控制制器應用技術.北京:機械工業出版社,1994
[3] 張萬忠.可編程式控制制器應用技術.北京:化學工業出版社,2001.12
[4] 於慶廣.可編程式控制制器原理及系統設計.北京:清華大學出版社.2004

PLC,俗稱「電力線上網」,英文全名為Power Line Communication,主要是指利用電力線傳輸數據和話音信號的一種通信方式
1、主要特點

① 結構靈活,不受環境的限制,有電即可組建網路,同時可以靈活擴展接入埠數量,使資源保持較高的利用率,在移動性方面可與WLAN媲美。

② 傳輸質量高、速度快、帶寬穩定,可以很平順的在線觀賞DVD影片,它所提供的14Mbps帶寬可以為很多應用平台提供保證。最新的電力線標准HomePlug AV傳輸速度已經達到了200Mbps;為了確保QoS,HomePlug AV採用了時分多路訪問(TDMA)與帶有沖突檢測機能的載體偵聽多路訪問(CSMA)協議,兩者結合,能夠很好地傳輸流媒體。

③ 范圍廣,無所不在的電力線網路也是這種技術的優勢。雖然無線網路可以做到不破牆,但對於高層建築來說,其必需布設N多個AP才能滿足需求,而且同樣不能避面信號盲區的存在。而電力線是最基礎的網路,它的規模之大,是其他任何網路無法比擬的。由此,運營商就可以輕松地把這種網路接入服務滲透到每一處有電力線的地方。這一技術一旦全面進入商業化階段,將給互聯網普及帶來極大的發展空間。終端用戶只需要插上電力貓,就可以實現網際網路接入,電視頻道接收節目,打電話或者是可視電話。

④ 低成本。充分利用現有的低壓配電網路基礎設施,無需任何布線,節約了資源。無需挖溝和穿牆打洞,避免了對建築物、公用設施、家庭裝潢的破壞,同時也節省了人力。相對傳統的組網技術,PLC成本更低,工期短,可擴展性和可管理性更強。目前國內已開通電力寬頻上網的地方,其包月使用費用一般為50-80元/月左右,這樣的價格和很多地方的ADSL包月相持平。

⑤ 適用面廣。PLC作為利用電力線組網的一種接入技術,提供寬頻網路「最後一公里」的解決方案,廣泛適用於居民小區,酒店,辦公區,監控安防等領域。它是利用電力線作為通信載體,使得PLC具有極大的便捷性,只要在房間任何有電源插座的地方,不用撥號,就立即可享受4.5~45Mbps的高速網路接入,來瀏覽網頁、撥打電話,和觀看在線電影,從而實現集數據、語音、視頻,以及電力於一體的「四網合一」。

PLC 還有一種說法是:產品生命周期(proct life cycle)觀念,簡稱PLC,是把一個產品的銷售歷史比作象人的生命周期一樣,要經歷出生、成長、成熟、老化、死亡等階段。就產品而言,也就是要經歷一個開發、引進、成長、成熟、衰退的階段。
1、產品開發期:從開發產品的設想到產品製造成功的時期。此期間該產品銷售額為零,公司投資不斷增加。
2、引進期:新產品新上市,銷售緩慢。由於引進產品的費用太高,初期通常利潤偏低或為負數,但此時沒有或只有極少的競爭者。
3、成長期:產品經過一段時間已有相當知名度,銷售快速增長,利潤也顯著增加。但由於市場及利潤成長較快,容易吸引更多的競爭者。
4、成熟期:此時市場成長趨勢減緩或飽和,產品已被大多數潛在購買者所接受,利潤在達到頂點後逐漸走下坡路。此時市場競爭激烈,公司為保持產品地位需投入大量的營銷費用。
5、衰退期:這期間產品銷售量顯著衰退,利潤也大幅度滑落。優勝劣汰,市場競爭者也越來越少。

『貳』 有關於VB對內存讀寫的操作,那位幫幫忙

暈,眼都花了~~給你篇文章看看把,VB用指針操作內存,就倆API

真沒想到VB也可以這樣用之指針技術

想當年東方不敗,黑木崖密室一戰,僅憑一根綉花針獨戰四大高手,神出鬼沒,堪稱天下武林第一高手。若想成為VB里的東方不敗,熟習VB《葵花寶典》,掌握VB指針技術,乃是不二的法門。

欲練神功,引刀……,其實掌握VB指針技術,並不需要那麼痛苦。因為說穿了,也就那麼幾招,再勤加練習,終可至神出鬼沒之境。廢話少說,讓我們先從指針的定義說起。

一、指針是什麼?

不需要去找什麼標準的定義,它就是一個32位整數,在C語言和在VB里都可以用Long類型來表示。在32位Windows平台下它和普通的32位長整型數沒有什麼不同,只不過它的值是一個內存地址,正是因為這個整數象針一樣指向一個內存地址,所以就有了指針的概念。

有統計表明,很大一部分程序缺陷和內存的錯誤訪問有關。正是因為指針直接和內存打交道,所以指針一直以來被看成一個危險的東西。以至於不少語言,如著名的JAVA,都不提供對指針操作的支持,所有的內存訪問方面的處理都由編譯器來完成。而象C和C++,指針的使用則是基本功,指針給了程序員極大的自由去隨心所欲地處理內存訪問,很多非常巧妙的東西都要依靠指針技術來完成。

關於一門高級的程序設計語言是不是應該取消指針操作,關於沒有指針操作算不算一門語言的優點,我在這里不討論,因為互聯網上關於這方面的沒有結果的討論,已經造成了佔用幾個GB的資源。無論最終你是不是要下定決心修習指針技術《葵花寶典》,了解這門功夫總是有益處的。

注意:在VB里,官方是不鼓勵使用什麼指針的,本文所講的任何東西你都別指望取得官方的技術支持,一切都要靠我們自己的努力,一切都更刺激!

讓我們開始神奇的VB指針探險吧!

二、來看看指針能做什麼?有什麼用?

先來看兩個程序,程序的功能都是交換兩個字串:

【程序一】:

'標準的做法SwapStr
Sub SwapStr(sA As String, sB As String)
Dim sTmp As String
sTmp = sA: sA = sB: sB = sTmp
End Sub

【程序二】:

'用指針的做法SwapPtr
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, ByVal Length As Long)

Sub SwapPtr(sA As String, sB As String)
Dim lTmp As Long
CopyMemory lTmp, ByVal VarPtr(sA), 4
CopyMemory ByVal VarPtr(sA), ByVal VarPtr(sB), 4
CopyMemory ByVal VarPtr(sB), lTmp, 4
End Sub

你是不是以為第一個程序要快,因為它看著簡單而且不用調用API(調用API需要額外的處理,VB文檔明確指出大量調用API將降低程序性能)。但事實上,在VB集成環境中運行,程序二要比程序一快四分之一;而編譯成本機代碼或p-code,程序二基本上要比程序一快一倍。下面是兩個函數在編譯成本機代碼後,運行不同次數所花時間的比較:

運行100000次,SwapStr需要170毫秒,SwapPtr需要90毫秒。

運行200000次,SwapStr需要340毫秒,SwapPtr需要170毫秒。

運行2000000次,SwapStr需要3300毫秒,SwapPtr需要1500毫秒。

的確,調用API是需要額外指令來處理,但是由於使用了指針技術,它沒有進行臨時字串的分配和拷貝,因此速度提高了不少。

怎麼樣,想不到吧!C/C++程序員那麼依賴指針,無非也是因為使用指針往往能更直接的去處理問題的根源,更有駕馭一切的快感。他們不是不知道使用指針的危險,他們不是不願意開衛星定位無級變速的汽車,只是騎摩托更有快感,而有些地方只有摩托才走得過去。
和在C里類似,在VB里我們使用指針也不過三個理由:

一是效率,這是一種態度一種追求,在VB里也一樣;

二是不能不用,因為操作系統是C寫的,它時刻都在提醒我們它需要指針;

三是突破限制,VB想照料我們的一切,VB給了我們很強的類型檢查,VB象我們老媽一樣,對我們關心到有時我們會受不了,想偶爾不聽媽媽的話嗎?你需要指針!

但由於缺少官方的技術支持,在VB里,指針變得很神秘。因此在C里一些基本的技術,在VB里就變得比較困難。本文的目的就是要提供給大家一種簡單的方法,來將C處理指針的技術拿到VB里來,並告訴你什麼是可行的,什麼可行但必須要小心的,什麼是可能但不可行的,什麼是根本就不可能的。
三、 程咬金的三板斧

是的,程序二基本上就已經讓我們看到VB指針技術的模樣了。總結一下,在VB里用指針技術我們需要掌握三樣東西:CopyMemory,VarPtr/StrPtr/ObjPtr, AdressOf. 三把斧頭,程咬金的三板斧,在VB里Hack的工具。

1、CopyMemory

關於CopyMemory和Bruce McKinney大師的傳奇,MSDN的Knowledge Base中就有文章介紹,你可以搜索"ID: Q129947"的文章。正是這位大師給32位的VB帶來了這個可以移動內存的API,也正是有了這個API,我們才能利用指針完成我們原來想都不敢想的一些工作,感謝Bruce McKinney為我們帶來了VB的指針革命。

如CopyMemory的聲明,它是定義在Kernel32.dll中的RtlMoveMemory這個API,32位C函數庫中的memcpy就是這個API的包裝,如MSDN文檔中所言,它的功能是將從Source指針所指處開始的長度為Length的內存拷貝到Destination所指的內存處。它不會管我們的程序有沒有讀寫該內存所應有的許可權,一但它想讀寫被系統所保護的內存時,我們就會得到著名的Access Violation Fault(內存越權訪問錯誤),甚至會引起更著名的general protection (GP) fault(通用保護錯誤) 。所以,在進行本系列文章里的實驗時,請注意隨時保存你的程序文件,在VB集成環境中將"工具"->"選項"中的"環境"選項卡里的"啟動程序時"設為"保存改變",並記住在"立即"窗口中執行危險代碼之前一定要保存我們的工作成果。

2、VatPtr/StrPtr/ObjPtr

它們是VB提供給我們的好寶貝,它們是VBA函數庫中的隱藏函數。為什麼要隱藏?因為VB開發小組,不鼓勵我們用指針嘛。

實際上這三個函數在VB運行時庫MSVBVM60.DLL(或MSVBVM50.DLL)中是同一個函數VarPtr(可參見我在本系列第一篇文章里介紹的方法)。

其庫型庫定義如下:

[entry("VarPtr"), hidden]
long _stdcall VarPtr([in] void* Ptr);
[entry("VarPtr"), hidden]
long _stdcall StrPtr([in] BSTR Ptr);
[entry("VarPtr"), hidden]
long _stdcall ObjPtr([in] IUnknown* Ptr);

即然它們是VB運行時庫中的同一個函數,我們也可以在VB里用API方式重新聲明這幾個函數,如下:

Private Declare Function ObjPtr Lib "MSVBVM60" Alias "VarPtr" (var As Object) As Long
Private Declare Function VarPtr Lib "MSVBVM60" (var As Any) As Long

(沒有StrPtr,是因為VB對字元串處理方式有點不同,這方面的問題太多,我將在另一篇文章中詳談。順便提一下,聽說VB.NET里沒有這幾個函數,但只要還能調用API,我們就可以試試上面的幾個聲明,這樣在VB.NET里我們一樣可以進行指針操作。但是請注意,如果通過API調用來使用VarPtr,整個程序二SwapPtr將比原來使用內置VarPtr函數時慢6倍。)

如果你喜歡刨根問底,那麼下面就是VarPtr函數在C和匯編語言里的樣子:

在C里樣子是這樣的:

long VarPtr(void* pv){
return (long)pv;
}

所對就的匯編代碼就兩行:

mov eax,dword ptr [esp+4]
ret 4 '彈出棧里參數的值並返回。

之所以讓大家了解VarPtr的具體實現,是想告訴大家它的開銷並不大,因為它們不過兩條指令,即使加上參數賦值、壓棧和調用指令,整個獲取指針的過程也就六條指令。當然,同樣的功能在C語言里,由於語言的直接支持,僅需要一條指令即可。但在VB里,它已經算是最快的函數了,所以我們完全不用擔心使用VarPtr會讓我們失去效率!速度是使用指針技術的根本要求。

一句話,VarPtr返回的是變數所在處的內存地址,也可以說返回了指向變數內存位置的指針,它是我們在VB里處理指針最重要的武器之一。

3、ByVal和ByRef

ByVal傳遞的參數值,而ByRef傳遞的參數的地址。在這里,我們不用去區別傳指針/傳地址/傳引用的不同,在VB里,它們根本就是一個東西的三種不同說法,即使VB的文檔里也有地方在混用這些術語(但在C++里的確要區分指針和引用)

初次接觸上面的程序二SwapPtr的朋友,一定要搞清在裡面的CopyMemory調用中,在什麼地方要加ByVal,什麼地方不加(不加ByVal就是使用VB預設的ByRef),准確的理解傳值和傳地址(指針)的區別,是在VB里正確使用指針的基礎。

現在一個最簡單的實驗來看這個問題,如下面的程序三:

【程序三】:

'體會ByVal和ByRef
Sub TestCopyMemory()
Dim k As Long
k = 5
Note: CopyMemory ByVal VarPtr(k), 40000, 4
Debug.Print k
End Sub

上面標號Note處的語句的目的,是將k賦值為40000,等同於語句k=40000,你可以在"立即"窗口試驗一下,會發現k的值的確成了40000。
實際上上面這個語句,翻譯成白話,就是從保存常數40000的臨時變數處拷貝4個位元組到變數k所在的內存中。

現在我們來改變一個Note處的語句,若改成下面的語句:

Note2: CopyMemory ByVal VarPtr(k), ByVal 40000, 4

這句話的意思就成了,從地址40000拷貝4個位元組到變數k所在的內存中。由於地址40000所在的內存我們無權訪問,操作系統會給我們一個Access Violation內存越權訪問錯誤,告訴我們"試圖讀取位置0x00009c40處內存時出錯,該內存不能為'Read'"。

我們再改成如下的語句看看。

Note3: CopyMemory VarPtr(k), 40000, 4

這句話的意思就成了,從保存常數40000的臨時變數處拷貝4個位元組到到保存變數k所在內存地址值的臨時變數處。這不會出出內存越權訪問錯誤,但k的值並沒有變。

我們可以把程序改改以更清楚的休現這種區別,如下面的程序四:

【程序四】:

'看看我們的東西被拷貝到哪兒去了
Sub TestCopyMemory()
Dim i As Long, k As Long
k = 5
i = VarPtr(k)
NOTE4: CopyMemory i, 40000, 4
Debug.Print k
Debug.Print i
i = VarPtr(k)
NOTE5: CopyMemory ByVal i, 40000, 4
Debug.Print k
End Sub

程序輸出:

5
40000
40000

由於NOTE4處使用預設的ByVal,傳遞的是i的地址(也就是指向i的指針),所以常量40000拷貝到了變數i里,因此i的值成了40000,而k的值卻沒有變化。但是,在NOTE4前有:i=VarPtr(k),本意是要把i本身做為一個指針來使用。這時,我們必須如NOTE5那樣用ByVal來傳遞指針i,由於i是指向變數k的指針,所以最後常量40000被拷貝了變數k里。

希望你已經理解了這種區別,在後面問題的討論中,我還會再談到它。
4、AddressOf

它用來得到一個指向VB函數入口地址的指針,不過這個指針只能傳遞給API使用,以使得API能回調VB函數。

本文不準備詳細討論函數指針,關於它的使用請參考VB文檔。

5、拿來主義

實際上,有了CopyMemory,VarPtr,AddressOf這三把斧頭,我們已經可以將C里基本的指針操作拿過來了。

如下面的C程序包括了大部分基本的指針指針操作:

struct POINT{
int x; int y;
};

int Compare(void* elem1, void* elem2){}

void PtrDemo(){
//指針聲明:
char c = 'X'; //聲明一個char型變數
char* pc; long* pl; //聲明普通指針
POINT* pPt; //聲明結構指針
void* pv; //聲明無類型指針
int (*pfnCastToInt)(void *, void*);//聲明函數指針:
//指針賦值:
pc = &c; //將變數c的地址值賦給指針pc
pfnCompare = Compare; //函數指針賦值。
//指針取值:
c = *pc; //將指針pc所指處的內存值賦給變數c
//用指針賦值:
*pc = 'Y' //將'Y'賦給指針pc所指內存變數里。
//指針移動:
pc++; pl--;
}

這些對指針操作在VB里都有等同的東西,前面討論ByVal和ByRef時曾說過傳指針和傳地址是一回事,實際上當我們在VB里用預設的ByRef聲明函數參數時,我們已經就聲明了指針。

如一個C聲明的函數:long Func(char* pc)

其對應的VB聲明是:Function Func(pc As Byte) As Long

這時參數pc使用預設的ByRef傳地址方式來傳遞,這和C里用指針來傳遞參數是一樣。

那麼怎麼才能象C里那樣明確地聲明一個指針呢?

很簡單,如前所說,用一個32位長整數來表達指針就行。在VB里就是用Long型來明確地聲明指針,我們不用區分是普通指針、無類型指針還是函數指針,通通都可用Long來聲明。而給一個指針賦值,就是賦給它用VarPar得到的另一個變數的地址。具體見程序五。

【程序五】:同C一樣,各種指針。

Type POINT
X As Integer
Y As Integer
End Type

Public Function Compare(elem1 As Long, elem2 As Long) As Long
'
End Function

Function FnPtrToLong(ByVal lngFnPtr As Long) As Long
FnPtrToLong = lngFnPtr
End Function

Sub PtrDemo()
Dim l As Long, c As Byte, ca() As Byte, Pt As POINT
Dim pl As Long, pc As Long, pv As Long, pPt As Long, pfnCompare As Long
c = AscB("X")
pl = VarPtr(l) '對應C里的long、int型指針
pc = VarPtr(c) '對應char、short型指針
pPt = VarPtr(Pt) '結構指針
pv = VarPtr(ca(0)) '位元組數組指針,可對應任何類型,也就是void*
pfnCompare = FnPtrToLong(AddressOf Compare) '函數指針
CopyMemory c, ByVal pc, LenB(c) '用指針取值
CopyMemory ByVal pc, AscB("Y"), LenB(c) '用指針賦值
pc = pc + LenB(c) : pl = pl - LenB(l) '指針移動
End Sub

我們看到,由於VB不直接支持指針操作,在VB里用指針取值和用指針賦值都必須用CopyMemory這個API,而調用API的代價是比較高的,這就決定了我們在VB里使用指針不能象在C里那樣自由和頻繁,我們必須要考慮指針操作的代價,在後面的"指針應用"我們會再變談這個問題。

程序五中關於函數指針的問題請參考VB文檔,無類型指針void*會在下面"關於Any的問題"里說。

程序五基本上已經包括了我們能在VB里進行的所有指針操作,僅此而已。

下面有一個小測試題,如果現在你就弄懂了上面程咬金的三板斧,你就應該能做得出來。

上面提到過,VB.NET中沒有VarPtr,我們可以用聲明API的方式來引入MSVBVM60.DLL中的VarPtr。現在的問題如果不用VB的運行時DLL文件,你能不能自己實現一個ObjPtr。答案在下一節後給出。
四、指針使用中應注意的問題

1、關於ANY的問題

如果以一個老師的身份來說話,我會說:最好永遠也不要用Any!是的,我沒說錯,是永遠!所以我沒有把它放在程咬金的三板斧里。當然,這個問題和是不是應該使用指針這個問題一樣會引發一場沒有結果的討論,我告訴你的只是一個觀點,因為有時我們會為了效率上的一點點提高或想偷一點點懶而去用Any,但這樣做需要要承擔風險。

Any不是一個真正的類型,它只是告訴VB編譯器放棄對參數類型的檢查,這樣,理論上,我們可以將任何類型傳遞給API。

Any在什麼地方用呢?讓我們來看看,在VB文檔里的是怎麼說的,現在就請打開MSDN(Visual Studio 6自帶的版本),翻到"Visual Basic文檔"->"使用Visual Basic"->"部件工具指南"->"訪問DLL和Windows API"部分,再看看"將 C 語言聲明轉換為 Visual Basic 聲明"這一節。文檔里告訴我們,只有C的聲明為LPVOID和NULL時,我們才用Any。實際上如果你願意承擔風險,所有的類型你都可以用Any。當然,也可以如我所說,永遠不要用Any。

為什麼要這樣?那為什麼VB官方還要提供Any?是信我的,還是信VB官方的?有什麼道理不用Any?

如前面所說,VB官方不鼓勵我們使用指針。因為VB所標榜的優點之一,就是沒有危險的指針操作,所以的內存訪問都是受VB運行時庫控制的。在這一點上,JAVA語言也有著同樣的標榜。但是,同JAVA一樣,VB要避免使用指針而得到更高的安全性,就必須要克服沒有指針而帶來的問題。VB已經盡最大的努力來使我們遠離指針的同時擁有強類型檢查帶來的安全性。但是操作系統是C寫的,裡面到處都需要指針,有些指針是沒有類型的,就是C程序員常說的可怕的void*無類型指針。它沒有類型,因此它可以表示所有類型。如CopyMemory所對應的是C語言的memcpy,它的聲明如下:

void *memcpy( void *dest, const void *src, size_t count );

因memcpy前兩個參數用的是void*,因此任何類型的參數都可以傳遞給他。

一個用C的程序員,應該知道在C函數庫里這樣的void*並不少見,也應該知道它有多危險。無論傳遞什麼類型的變數指針給上面memcpy的void*,C編譯器都不會報錯或給任何警告。

在VB里大多數時候,我們使用Any就是為了使用void*,和在C里一樣,VB也不對Any進行類型檢查,我們也可以傳遞任何類型給Any,VB編譯器也都不會報錯或給任何警告。

但程序運行時會不會出錯,就要看使用它時是不是小心了。正因為在C里很多錯誤是和void*相關的,所以,C++鼓勵我們使用satic_cast<void*>來明確指出這種不安全的類型的轉換,已利於發現錯誤。

說了這么多C/C++,其實我是想告訴所有VB的程序員,在使用Any時,我們必須和C/C++程序員使用void*一樣要高度小心。

VB里沒有satic_cast這種東西,但我們可以在傳遞指針時明確的使用long類型,並且用VarPtr來取得參數的指針,這樣至少已經明確地指出我們在使用危險的指針。如程序二經過這樣的處理就成了下面的程序:

【程序五】:

'使用更安全的CopyMemory,明確的使用指針!
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
Sub SwapStrPtr2(sA As String, sB As String)
Dim lTmp As Long
Dim pTmp As Long, psA As Long, psB As Long
pTmp = VarPtr(lTmp): psA = VarPtr(sA): psB = VarPtr(sB)
CopyMemory pTmp, psA, 4
CopyMemory psA, psB, 4
CopyMemory psB, pTmp, 4
End Sub

注意,上面CopyMemory的聲明,用的是ByVal和long,要求傳遞的是32位的地址值,當我們將一個別的類型傳遞給這個API時,編譯器會報錯,比如現在我們用下面的語句:

【程序六】:

'有點象【程序四】,但將常量40000換成了值為1的變數.
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, Length As Long)
Sub TestCopyMemory()
Dim i As Long,k As Long, z As Interger
k = 5 : z = 1
i = VarPtr(k)
'下面的語句會引起類型不符的編譯錯誤,這是好事!
'CopyMemory i, z, 4
'應該用下面的
CopyMemory i, ByVal VarPtr(z), 2
Debug.Print k
End Sub

編譯會出錯!是好事!這總比運行時不知道錯在哪兒好!

象程序四那樣使用Any類型來聲明CopyMemory的參數,VB雖然不會報錯,但運行時結果卻是錯的。不信,你試試將程序四中的40000改為1,結果i的值不是我們想要的1,而是327681。為什麼在程序四中,常量為1時結果會出錯,而常量為40000時結果就不錯?

原因是VB對函數參數中的常量按Variant的方式處理。是1時,由於1小於Integer型的最大值32767,VB會生成一個存儲值1的Integer型的臨時變數,也就是說,當我們想將1用CopyMemroy拷貝到Long型的變數i時,這個常量1是實際上是Integer型臨時變數!VB里Integer類型只有兩個位元組,而我們實際上拷貝了四個位元組。知道有多危險了吧!沒有出內存保護錯誤那隻是我們的幸運!

如果一定要解釋一下為什麼i最後變成了327681,這是因為我們將k的低16位的值5也拷貝到了i值的高16位中去了,因此有5*65536+1=327681。詳談這個問題涉及到VB局部變數聲明順序,CopyMemory參數的壓棧順序,long型的低位在前高位在後等問題。如果你對這些問題感興趣,可以用本系列第一篇文章所提供的方法(DebugBreak這個API和VC調試器)來跟蹤一下,可以加深你對VB內部處理方式的認識,由於這和本文討論的問題無關,所以就不詳談了。到這里,大家應該明白,程序三和程序四實際上有錯誤!!!我在上面用常量40000而不用1,不是為了在文章中湊字數,而是因為40000這個常量大於32767,會被VB解釋成我們需要的Long型的臨時變數,只有這樣程序三和程序四才能正常工作。對不起,我這樣有意的隱藏錯誤只是想加深你對Any危害的認識。

總之,我們要認識到,編譯時就找到錯誤是非常重要的,因為你馬上就知道錯誤的所在。所以我們應該象程序五和程序六那樣明確地用long型的ByVal的指針,而不要用Any的ByRef的指針。

但用Any已經如此的流行,以至很多大師們也用它。它唯一的魅力就是不象用Long型指針那樣,需要我們自己調用VarPtr來得到指針,所有處理指針的工作由VB編譯器來完成。所以在參數的處理上,只用一條匯編指令:push ,而用VarPtr時,由於需要函數調用,因此要多用五條匯編指令。五條多餘的匯編指令有時的確能我們冒著風險去用Any。

VB開發小組提供Any,就是想用ByRef xxx As Any來表達void* xxx。我們也完全可以使用VarPtr和Long型的指針來處理。我想,VB開發小組也曾猶豫過是公布VarPtr,還是提供Any,最後他們決定還是提供Any,而繼續隱瞞VarPtr。的確,這是個兩難的決定。但是經過我上面的分析,我們應該知道,這個決定並不符合VB所追求的"更安全"的初衷。因為它可能會隱藏類型不符的錯誤,調試和找到這種運行時才產生的錯誤將花貴更多的時間和精力。

所以我有了"最好永遠不要用Any"這個"驚人"的結論。

不用Any的另一個好處是,簡化了我們將C聲明的API轉換成VB聲明的方式,現在它變成了一句話:除了VB內置的可以進行類型檢查的類型外,所以其它的類型我們都應該聲明成Long型。

2、關於NULL的容易混淆的問題

有很多文章講過,一定要記在心裡:

VbNullChar 相當於C里的'\0',在用位元組數組構造C字串時常用它來做最後1個元素。

vbNullString 這才是真正的NULL,就是0,在VB6中直接用0也可以。

只有上面的兩個是API調用中會用的。還有Empty、Null是Variant,而Nothing只和類對象有關,一般API調用中都不會用到它們。

另:本文第三節曾提出一個小測驗題,做出來了嗎?現在公布正確答案:

【測驗題答案】

Function ObjPtr(obj as Object) as long
Dim lpObj As Long
CopyMemory lpObj, Obj, 4
ObjectPtr = lpObj
End Function

五、VB指針應用

如前面所說VB里使用指針不象C里那樣靈活,用指針處理數據時都需要用CopyMemory將數據在指針和VB能夠處理的變數之間來回拷貝,這需要很大的額外開銷。因此不是所有C里的指針操作都可以移值到VB里來,我們只應在需要的時候才在VB里使用指針。

1、動態內存分配:完全不可能、可能但不可行,VB標准

在C和C++里頻繁使用指針的一個重要原因是需要使用動態內存分配,用Malloc或New來從堆棧里動態分配內存,並得到指向這個內存的指針。在VB里我們也可以自己

用API來實現動態分配內存,並且實現象C里的指針鏈表。

但我們不可能象C那樣直接用指針來訪問這樣動態分配的內存,訪問時我們必須用CopyMemory將數據拷貝到VB的變數內,大量的使用這種技術必然會降低效率,以至於要象C那樣用指針來使用動態內存根本就沒有可行性。要象C、PASCAL那樣實現動態數據結構,在VB里還是應該老老實實用對象技術來實現。

本文配套代碼中的LinkedList里有完全用指針實現的鏈表,它是使用HeapAlloc從堆棧中動態分配內存,另有一個調用FindFirstUrlCacheEntry這個API來操作IE的Cache的小程序IECache,它使用了VirtualAlloc來動態分配內存。但實際上這都不是必須的,VB已經為我們提供了標準的動態內存分配的方法,那就是:

對象、字元串和位元組數組

限於篇幅,關於對象的技術這里不講,LinkedList的源代碼里有用對象實現的鏈表,你可以參考。

字元串可以用Space$函數來動態分配,VB的文檔里就有詳細的說明。

關於位元組數組,這里要講講,它非常有用。我們可用Redim來動態改變它的大小,並將指向它第一個元素的指針傳給需要指針的API,如下:

dim ab() As Byte , ret As long
'傳遞Null值API會返回它所需要的緩沖區的長度。
ret = SomeApiNeedsBuffer(vbNullString)
'動態分配足夠大小的內存緩沖區
ReDim ab(ret) As Byte
'再次把指針

『叄』 pid控制的C語言編程

#include<unistd.h>
#include<stdio.h>
int main(int argc,int **argv)
{
int pid=fork();
if(pid==-1)
{
printf("error");
}
else if(pid==0)
{
printf("This is the child process!\n");
}
else
{
printf("This is the parent process! child process id=%d\n",pid);
}
return 0;
}
首先為什麼這段代碼gcc編沒兆譯不了,只能用g++編譯,gcc編譯顯示結果如下
Undefined first referenced
symbol in file
__gxx_personality_v0 /var/tmp//ccuHN8IS.o
ld: fatal: Symbol referencing errors. No output written to t5
collect2: ld returned 1 exit status
其次,g++編譯橋察租後運行結果敏兆如下
This is the parent process! child process id=27406
This is the child process!

閱讀全文

與pidc編譯器相關的資料

熱點內容
time庫中的clock函數python 瀏覽:987
cad視覺移動命令怎麼打開 瀏覽:819
安卓java調用python 瀏覽:395
java標准時間 瀏覽:137
華為伺服器湖北渠道商雲主機 瀏覽:30
韓式面部護理解壓視頻 瀏覽:301
pdf換成jpg圖片 瀏覽:897
dh加密演算法 瀏覽:107
安卓手機如何隱藏微信信息提示 瀏覽:632
nodejs解壓縮 瀏覽:262
直流雙轉子壓縮機 瀏覽:952
pythonxmlstring 瀏覽:822
用私鑰加密之後可以用公鑰解密 瀏覽:788
ug如何啟動伺服器 瀏覽:444
csgo防抖動命令 瀏覽:960
如何弄到手機app頁面的源碼 瀏覽:441
androidwindows7破解版 瀏覽:363
解壓視頻動畫怎麼拍 瀏覽:748
連漲啟動源碼 瀏覽:163
小奔運動app網路異常怎麼回事 瀏覽:449