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

  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_intC++編譯器開發商已經對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預處理指令的作用是在指令處展開被包含的文件,包含可以是多重的,也就是說,一個被包含的文件中海可以包含其他的文件。

      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系統編程中用的較多,比如MouseProGetMsgProcEnumWindowsDrawState

例如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中,宏WINAPICALLBACK都定義為_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>
            伊人成人网在线看| 日韩一级片网址| 亚洲国产合集| 一区二区视频免费完整版观看| 欧美精品在线观看播放| 亚洲美女av在线播放| 欧美激情精品久久久久久蜜臀| 久久乐国产精品| 久久久噜噜噜久久人人看| 久久免费精品日本久久中文字幕| 久久资源av| 欧美精品日韩一本| 欧美日韩国产欧| 国产精品你懂的在线欣赏| 国产日本欧美一区二区三区| 国产一级精品aaaaa看| 狠狠色综合色区| 最新日韩av| 另类国产ts人妖高潮视频| 久久久91精品| 欧美日韩日本视频| 国产日韩亚洲| 亚洲精品九九| 久久激情中文| 亚洲高清在线观看| 日韩一级大片在线| 久久精品动漫| 欧美视频在线播放| 在线欧美日韩| 亚洲在线免费| 欧美激情一区二区在线| 亚洲校园激情| 欧美国产精品久久| 国产资源精品在线观看| 中日韩视频在线观看| 久久视频一区| 在线中文字幕不卡| 美日韩精品免费观看视频| 国产精品乱子久久久久| 日韩视频第一页| 久久久久在线观看| 一卡二卡3卡四卡高清精品视频| 久久er99精品| 亚洲欧美国产高清va在线播| 午夜精品免费在线| 亚洲二区免费| 中文精品一区二区三区| 欧美成人午夜剧场免费观看| 国产视频一区免费看| 亚洲视频在线一区| 欧美激情中文不卡| 久久精品在线| 亚洲免费av观看| 久久精品免费电影| 国产日韩一区在线| 欧美一区三区二区在线观看| 日韩亚洲精品视频| 欧美国产乱视频| 亚洲日本精品国产第一区| 老司机成人在线视频| 亚洲国产一成人久久精品| 国产一区清纯| 国产精品一二三四| 亚洲国产婷婷香蕉久久久久久| 久久久久久自在自线| 午夜精品久久久久久久| 国产精品白丝黑袜喷水久久久| 在线视频亚洲欧美| 日韩天天综合| 欧美午夜不卡视频| 一区二区三区四区在线| 亚洲精品在线看| 欧美日韩一区二区视频在线观看| 亚洲最新中文字幕| 夜夜精品视频一区二区| 国产精品久久久久久久久久直播| 性色av一区二区三区| 先锋影音一区二区三区| 欧美日韩国产成人精品| 一区二区三区高清视频在线观看| 欧美国产高潮xxxx1819| 欧美一区二区福利在线| 国产在线一区二区三区四区| 久久夜色精品亚洲噜噜国产mv | 亚洲久色影视| 亚洲激情在线观看视频免费| 欧美日产国产成人免费图片| 亚洲少妇一区| 欧美一级在线视频| 91久久精品美女高潮| 99re热这里只有精品视频| 国产精品美女www爽爽爽| 久久精品国产免费看久久精品| 久久国产精品99久久久久久老狼 | 久久se精品一区二区| 这里只有视频精品| 欧美风情在线观看| 欧美精品国产精品| 小黄鸭视频精品导航| 久久久精品日韩| 亚洲最新中文字幕| 一区二区三区国产在线观看| 亚洲欧美激情视频| 亚洲国产精品一区二区第四页av| 一本一本久久| 在线观看免费视频综合| 宅男噜噜噜66国产日韩在线观看| 激情五月婷婷综合| 一本色道婷婷久久欧美| 亚洲激情偷拍| 久久不见久久见免费视频1| 日韩午夜电影| 欧美一区二区三区四区在线 | 亚洲天堂av高清| 一区二区三区黄色| 午夜精品在线视频| 亚洲人成在线播放| 久久成人精品视频| 亚洲伊人网站| 欧美激情综合| 欧美成人精品在线播放| 国产日韩精品电影| 亚洲第一在线视频| 国产一区清纯| 亚洲欧美日韩天堂| 亚洲欧美精品在线| 欧美日韩国产在线看| 免费观看一级特黄欧美大片| 国产日韩一区二区| 先锋影音一区二区三区| 欧美一二区视频| 国产精品视区| 亚洲一区免费观看| 亚洲一区免费| 国产精品美女久久久免费| 9久re热视频在线精品| 一本色道综合亚洲| 欧美日韩免费一区| 在线亚洲一区| 欧美一区日韩一区| 国产欧美午夜| 欧美一区网站| 老牛嫩草一区二区三区日本| 激情婷婷欧美| 欧美/亚洲一区| 亚洲人精品午夜在线观看| 亚洲乱码一区二区| 欧美日韩视频第一区| 中文av一区特黄| 久久不射电影网| 国内精品嫩模av私拍在线观看| 久久精品一区二区三区不卡牛牛| 美女视频一区免费观看| 亚洲国产经典视频| 欧美精品麻豆| 亚洲欧美另类在线观看| 久久网站免费| 亚洲美女在线国产| 国产精品久久久久一区二区三区| 欧美亚洲三区| 欧美激情精品久久久久久大尺度| 99pao成人国产永久免费视频| 国产精品二区在线观看| 欧美一区二区三区在| 欧美成人a视频| 亚洲视频综合在线| 国产日韩欧美高清免费| 久久一日本道色综合久久| 亚洲茄子视频| 欧美在线免费视频| 国产精品嫩草99a| 精品成人在线| 娇妻被交换粗又大又硬视频欧美| 久久久久国内| 亚洲精品美女在线观看| 久久一区二区精品| 91久久久亚洲精品| 午夜精品免费视频| 久久九九电影| 亚洲午夜久久久| 亚洲色图制服丝袜| 国产精品老牛| 久久久午夜视频| 一本一本久久a久久精品综合麻豆| 欧美制服第一页| 1024欧美极品| 国产精品久久久久久影视| 久久亚洲精品中文字幕冲田杏梨 | 国产日韩欧美三级| 国产精品亚洲人在线观看| 在线观看精品一区| 欧美在线一级视频| 男同欧美伦乱| 亚洲欧美日韩精品久久亚洲区| 好吊妞这里只有精品| 欧美体内谢she精2性欧美| 久久麻豆一区二区| 亚洲一区二区成人在线观看| 蜜臀av性久久久久蜜臀aⅴ| 亚洲一区免费|