青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  117 Posts :: 2 Stories :: 61 Comments :: 0 Trackbacks

常用鏈接

留言簿(8)

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

      函數是C++語言的基本功能單位,一般來說,函數的功能單一,函數代碼不可過長。函數接口設計清晰明了,返回值和錯誤代碼的返回分開。除了普通的函數之外,還有內聯函數、回調函數等。在不同語言之間的調用函數,提供了不同的調用規范。所謂預處理是指在進行編譯的第一遍掃描(詞法掃描和語法分析)之前所做的工作。預處理是C++語言的一個重要功能,它由預處理程序負責完成。當對一個源文件進行編譯時,系統將自動引用預處理程序對源程序中的預處理部分進行處理,處理完畢自動進入對源程序的編譯。C++語言提供了多種預處理功能,如宏定義、文件包含、條件編譯等。合理地使用預處理功能編寫的程序便于閱讀、修改、移植和調試,也有利于模塊化程序設計。

1、 在C++中調用C編譯器的函數

      1.1   C++中調用C編譯器的函數的原理

      C++語言,曾經有一叫法是帶類的C語言,那也就是說它的前身是C語言,所以說,用C寫的函數,基本上是可以在C++中調用的。比如說,C語言標準庫中的函數,在C++中是可以調用的。但是    C++畢竟跟C不同,那怎樣才能順利地把C函數應用到C++中呢?下面來討論這個問題。

      C++語言支持函數重載,C語言不支持函數重載。函數被C++編譯后在庫中的名字與C語言的不同。

      1.2   實例代碼

      假設某個C函數的聲明如下:

    void foo(int x, int y);

      該函數被C編譯器編譯后在庫中的名字為_foo,而C++編譯器則會產生像_foo_int_int之類的名字用來支持函數重載和類型安全連接。由于編譯后的名字不同,C++程序不能直接調用C函數。C++提供了一個C連接交換指定符號extern”C”來解決這個問題。例如

extern “C”
{
void foo(int x, int y);
//其他函數
}

或者寫成
extern “C”
{
#include “myheader.h”
//其他C頭文件
}

      這就告訴C++編譯器,函數foo是個C連接,應該到庫中找名字_foo而不是找_foo_int_int。C++編譯器開發商已經對C標準庫的頭文件做了extern”C”處理,所以可以用#include直接引用這些頭文件。

      如果調用自己寫的C函數,可以把C函數集合成一個庫,然后把其相應的頭文件用extern”C”處理,用#include直接引用這些頭文件即可。

2、 內聯函數和宏的比較

      2.1 內聯函數的概念

      在C++中,可以將函數指定為內聯(inline)的,這樣,編譯器會在調用該函數的每個地方產生該函數的一個副本。使用內聯函數可以減少函數調用帶來的開銷,不過應該在函數很簡單而且在調用次數相對較少的情況下,才將其指定為內聯的。

      內聯函數的基本思想在于將每個函數調用以它的代碼體來替換。用不著統計專家出面就可以看出,這種做法很可能會增加整個目標代碼的體積。在一臺內存有限的計算機里,過分地使用內聯所產生的程序會因為有太大的體積而導致可用空間不夠。即使可以使用虛擬內存,內聯造成的代碼膨脹也可能會導致不合理的頁面調度行為(系統顛簸),這將使你的程序運行慢得象在爬。(當然,它也為磁盤控制器提供了一個極好的鍛煉方式:)
      過多的內聯還會降低指令高速緩存的命中率,從而使取指令的速度降低,因為從主存取指令當然比從緩存要慢。另一方面,如果內聯函數體非常短,編譯器為這個函數體生成的代碼就會真的比為函數調用生成的代碼要小許多。如果是這種情況,內聯這個函數將會確實帶來更小的目標代碼和更高的緩存命中率!要牢記在心的一條是,
inline指令就象register,它只是對編譯器的一種提示,而不是命令。也就是說,只要編譯器愿意,它就可以隨意地忽略掉你的指令,事實上編譯器常常會這么做。例如,大多數編譯器拒絕內聯"復雜"的函數。
      摘自
Effective   C++2e,建議看一下《深度探索C++對象模型〉

      2.2 內聯函數和宏的比較

      兩者相同之處是,在其出現的地方將代碼替換。但是區別很大。

      對于宏來說,C++中不贊成使用,除非程序中一定要用宏時。宏只是在編譯前(編譯處理階段)將程序中有關字符串替換成宏體,也不進行參數類型等的檢查,容易出錯

      對于內聯函數來說,其不是通過函數調用實現的,是在調用該函數的程序處將它展開,這是在程序的編譯期間完成的,期間進行諸如類型檢測等過程,減少了錯誤的發生

      2.3 應用規則

      ·宏盡量少用,或不用。

      ·內聯函數不宜過大,過復雜

      ·內聯函數是建議性而非指令性的,過大或過復雜,會被系統忽略,而當成一般函數用了。

      ·內聯函數一般不要超過5行,而且經常要用時才聲明稱內聯函數

3、 #include<filename.h>和#include “filename.h”的區別

      3.1 包含文件

      #inculde預處理指令的作用是在指令處展開被包含的文件,包含可以是多重的,也就是說,一個被包含的文件中??梢园渌奈募?/span>

      3.2 包含頭文件有兩種格式

      一種就是#include<文件名>,另一種是#include ”文件名。

      用尖括號包括頭文件,這是C++的標準方式,一般這些頭文件都存放于C++系統目錄中的include子目錄下,C++預處理碰到這種情況后,就到include目錄下搜索給出的文件。

      用引號包括頭文件,適用于用戶自己寫的頭文件中,預處理碰到這種格式,就先在當前目錄下進行搜索,如果找不到,再到系統目錄下進行搜索。

4、 回調函數的概念與操作技巧

      4.1 回調函數的概念

      回調函數就是在調用某個函數(通常是API函數)時,將用戶自己的一個函數(這個函數為回調函數)的地址作為參數傳遞給那個函數。而那個函數在需要的時候,利用傳遞的地址調用用戶自己定義的函數,這時在回調函數中處理消息或完成一定得操作。

      4.2 回調函數的實現

      回調函數調用是利用其函數地址調用函數的,實現函數的功能。要實現一個回調函數,首先要實現一個函數指針,讓這個指針指向功能函數,然后利用函數指針,隱式調用函數。

#include<iostream.h>
//聲明功能函數:
void fun()
{
  cout
<<"this is a callback test"<<endl;
}

//聲明指針函數:
void (*p) (); //指針p指向一個參數為空,返回值為void的功能函數
//聲明調用函數caller,函數的參數是返回值為void,參數為空的函數指針:
void caller(void (*ptr)())
{
  ptr();
}

//主函數實現
int main()
{
  p
=fun;
  caller(p);
  
return 0;
}

       4.3 回調函數的應用

       回調函數在Windows系統編程中用的較多,比如MousePro、GetMsgProcEnumWindowsDrawState

例如API函數

EnumFonts(HDC hdc,
LPCTSTR lpFaceName,
FONTENUMPROC,
PARAM lParam
);

在使用時需要定義一個回調函數:

Int CALLBACK EnumFontsProc(
CONST LOCFONT 
*lplf,
CONST TEXTMETRIC 
*lptm,
DWORD dwTtype,
LPARAM lpDate
);

      然后寫EnumFonts(hdc,null,EnumFontsProc)即可。在使用計時器時,把計時器消息發送給程序的另一個函數,接收這些計時器消息的函數被稱為“回調”函數,這是一個在程序中,但是由Windows調用的函數。程序的窗口過程實際上也是一類回調函數,當注冊窗口類時,要將函數的地址告訴Windows,當發送消息給程序時,Windows調用此函數。

5、 函數的調用規范

      當程序被執行時,CPU無法知道函數的調用需要多少個、什么樣的參數,那么也就是說計算機無法知道如何給這個函數傳遞參數。函數的調用時由調用者和被調用者協作完成的。計算機為此專門提供了棧的數據結構,支持參數的傳遞。函數調用時,參數執行壓棧操作,然后開始調用函數,函數被調用以后,參數值出棧,參與函數功能實現后,進行棧的清理工作。在參數傳遞中,當參數多于一個時,按照什么順序壓棧,函數調用后,由誰把堆棧回復。

      在高級語言中,通過函數調用規范(Calling Conventions)來說明這三個問題。常見的調用規范有:stdcallcdecl

      1.    stdcall調用規范

      這是Win API函數使用的調用規范。參數從右向左一次傳遞并壓入堆棧,由被調用函數負責堆棧的清退。該規范生產代碼比_cdecl更小,但當函數有可變個數的參數時會轉為_cdecl規范。在Windows中,宏WINAPI、CALLBACK都定義為_stdcall。

      stdcall調用規范聲明的語法為:

int _stdcall function(int a, int b)

      利用stdcall調用,參數從右向左壓入堆棧,函數自身修改堆棧,調用時函數名自動加前導的下劃線,后面緊跟一個@符號,其后緊跟著參數的尺寸。以上述這個函數為例,參數b首先被壓棧,然后是參數a,函數調用function(1,2),而在編譯時,這個函數的名字被翻譯成_function@8

      2.   cdecl調用規范

      cdecl調用約定又被稱為C調用約定,是C語言默認的調用約定,它的定義語法是:

int function(int a, int b) //不加修飾就是C調用約定

int _cdecl function(int a, int b) //明確指出C調用約定

      cdecl調用約定的參數壓棧順序是和stdcall一樣的,參數首先由右向左壓入堆棧。所不同的是,函數本身不清理堆棧,調用者負責清理堆棧。由于這種變化,C調用約定允許函數的參數個數是不固定的,這也是C語言的一大特色。對于前面的function函數,該修飾自動在函數名前加前導的下劃線,因此函數名在符號表中被記錄為_function

      3.   函數調用約定導致的常見問題

      如果定義的約定和使用的約定不一致,將導致堆棧被破壞,導致嚴重問題,下面是兩種常見的問題。

      ·函數原型聲明和函數體定義不一致

      ·DLL導入函數時聲明了不同的函數約定

如果還想獲得更多關于《Visual C++代碼參考與技巧大全》的內容,可點擊下面網址,

http://m.shnenglu.com/kangnixi/archive/2010/01/13/105591.html

posted on 2010-01-26 14:05 煙皚 閱讀(488) 評論(0)  編輯 收藏 引用 所屬分類: 《Visual C++代碼參考與技巧大全》學習筆記
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            好看不卡的中文字幕| 久久久久久久久久看片| 亚洲自拍偷拍视频| 99精品热视频| 中文在线资源观看网站视频免费不卡 | 一区二区高清在线观看| 亚洲国产精品久久人人爱蜜臀| 国产一区欧美| 亚洲欧洲午夜| 亚洲女人天堂成人av在线| 久久精品国产99国产精品| 中文欧美日韩| 制服丝袜亚洲播放| 噜噜噜在线观看免费视频日韩| 午夜欧美电影在线观看| 免费毛片一区二区三区久久久| 麻豆乱码国产一区二区三区| 亚洲毛片在线观看.| 亚洲一区二区三区视频| 久久久久久夜精品精品免费| 亚洲精品美女免费| 亚洲国产小视频| 一区二区电影免费观看| 欧美91大片| 国产综合香蕉五月婷在线| 亚洲精品免费在线| 免费在线观看精品| 午夜久久一区| 国产精品亚洲成人| 亚洲一二三四区| 91久久线看在观草草青青| 久久大综合网| 国产主播一区二区| 久久精品国产精品| 久久av一区| 韩国一区电影| 美女黄色成人网| 久久激情中文| 亚洲国产欧美一区二区三区同亚洲 | 一区二区三区**美女毛片| 午夜欧美精品| 欧美日韩福利| 国产精品亚洲成人| 一区二区三区黄色| 亚洲日本乱码在线观看| 麻豆精品精品国产自在97香蕉| 雨宫琴音一区二区在线| 牛夜精品久久久久久久99黑人 | 亚洲激情国产| 亚洲美女91| 韩国精品一区二区三区| 欧美日韩一区二区在线观看| 欧美在线啊v一区| 欧美激情四色| 久久久久一本一区二区青青蜜月| 狼人天天伊人久久| 香蕉成人伊视频在线观看| 久久都是精品| 亚洲欧美日韩精品久久亚洲区| 久久久久成人精品| 亚洲香蕉在线观看| 麻豆精品网站| 久久久精品国产99久久精品芒果| 久久精品国产77777蜜臀| 亚洲欧美综合| 欧美日韩免费网站| 亚洲全部视频| 一本色道88久久加勒比精品 | 亚洲国产精品日韩| 亚洲欧美日韩中文视频| 亚洲国内高清视频| 久久精品视频在线播放| 亚洲一区自拍| 久久网站热最新地址| 欧美国产极速在线| 欧美激情自拍| 亚洲欧美日韩精品久久亚洲区 | 日韩视频在线一区| 国产精品vvv| 美女尤物久久精品| 另类亚洲自拍| 亚洲成人在线网站| 卡通动漫国产精品| 亚洲午夜高清视频| 欧美自拍偷拍| 91久久精品国产91久久| 国产女人精品视频| 欧美一区二区三区免费观看| 久久野战av| 亚洲乱码国产乱码精品精98午夜| 老牛国产精品一区的观看方式| 欧美77777| 亚洲一级网站| 在线精品一区| 国内外成人在线| 玖玖玖国产精品| 一区二区三区色| 裸体一区二区| 久久亚裔精品欧美| 亚洲在线观看免费视频| 亚洲福利免费| 在线日韩一区二区| 影音先锋亚洲一区| 国产精品久久国产愉拍 | 国产精品一区一区| 欧美日韩亚洲一区二区三区在线观看 | 国产欧美日韩激情| 欧美另类综合| 欧美1区视频| 久久免费国产精品1| 欧美一级网站| 久久欧美肥婆一二区| 小嫩嫩精品导航| 久久综合九九| 欧美粗暴jizz性欧美20| 久久精品网址| 欧美日韩伦理在线| 国产亚洲一区精品| 91久久综合| 免费看黄裸体一级大秀欧美| 日韩视频一区| 欧美激情免费观看| 国产精品一级在线| 亚洲一区二区在线免费观看视频 | 亚洲高清不卡av| 亚洲综合欧美| 国产精品久久久免费| 欧美日本亚洲视频| 亚洲伊人久久综合| 亚洲成色www8888| 老司机成人网| 国产欧美精品一区二区三区介绍| 亚洲福利小视频| 狂野欧美激情性xxxx欧美| 亚洲伊人伊色伊影伊综合网| 欧美日韩精品福利| 正在播放亚洲| 一本色道精品久久一区二区三区| 欧美a级理论片| 99精品免费视频| 亚洲激情成人| 中文一区字幕| 一区二区三区 在线观看视频| 久久久久久一区| 久久久久一区| 久久婷婷国产综合国色天香| 一区二区精品| av72成人在线| 影音先锋在线一区| 国产亚洲欧美一区| 欧美国产日韩一区| 国产精品欧美日韩久久| 欧美视频一区在线观看| 亚洲国产毛片完整版| 久久久精品五月天| 亚洲国产精品va在线观看黑人| 久久精品视频99| 蜜臀av一级做a爰片久久| 欧美成年人视频| 久色成人在线| 激情久久久久久| 久久精品免费观看| 亚洲国产精品久久人人爱蜜臀 | 99亚洲精品| 一区二区高清在线观看| 亚洲国产va精品久久久不卡综合| 欧美成人首页| aaa亚洲精品一二三区| 国产一区二区久久久| 久久久久久综合| 久久久综合香蕉尹人综合网| 久久精品99无色码中文字幕| 国产精品视频第一区| 午夜免费电影一区在线观看| 亚洲国产视频一区二区| 欧美激情成人在线| 欧美一级黄色网| 国产精品久久久对白| 国产日本精品| 好看的日韩av电影| 亚洲男人的天堂在线观看 | 亚洲欧美成人一区二区三区| 亚洲视频导航| 久久精品中文| 国产一区二区三区高清| 亚洲高清一区二区三区| 久久精品一区四区| 欧美亚洲自偷自偷| 香蕉久久久久久久av网站| 亚洲免费人成在线视频观看| 日韩一级黄色av| 亚洲美女91| 一本色道久久综合亚洲精品婷婷 | 国产精品视频免费一区| 欧美精品大片| 99视频精品全部免费在线| 欧美精品国产精品日韩精品| 欧美在线观看一区| 亚洲网在线观看| 日韩香蕉视频|