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

C++中宏的使用問(wèn)題詳解

 更新時(shí)間:2016年05月18日 08:47:17   投稿:hebedich  
宏替換是C/C++系列語(yǔ)言的技術(shù)特色,C/C++語(yǔ)言提供了強(qiáng)大的宏替換功能,源代碼在進(jìn)入編譯器之前,要先經(jīng)過(guò)一個(gè)稱為“預(yù)處理器”的模塊,這個(gè)模塊將宏根據(jù)編譯參數(shù)和實(shí)際編碼進(jìn)行展開(kāi),展開(kāi)后的代碼才正式進(jìn)入編譯器,進(jìn)行詞法分析、語(yǔ)法分析等等。

宏不遵循C++中關(guān)于范圍和類型的規(guī)則。這經(jīng)常導(dǎo)致一些微妙的或不那么微妙的問(wèn)題。因此,C++提供更適合其他的C++(譯注:原文為the rest of C++,當(dāng)指C++除了兼容C 以外的部分)的替代品,例如內(nèi)聯(lián)函數(shù)、模板與名字空間。

考慮一下:

#include "someheader.h"
struct S {
  int alpha;
  int beta;
};

如果某人(不明智地)地寫(xiě)了一個(gè)叫“alpha”或“beta”的宏,那么它將不會(huì)被編譯,或者被錯(cuò)誤地編譯,產(chǎn)生不可預(yù)知的結(jié)果。例如,“someheader.h”可能包含:

  #define alpha 'a'
  #define beta b[2]

將宏(而且僅僅是宏)全部大寫(xiě)的習(xí)慣,會(huì)有所幫助,但是對(duì)于宏并沒(méi)有語(yǔ)言層次上的保護(hù)機(jī)制。例如,雖然成員的名字包含在結(jié)構(gòu)體的內(nèi)部,但這無(wú)濟(jì)于事:在編譯器能夠正確地辨別這一點(diǎn)之前,宏已經(jīng)將程序作為一個(gè)字符流進(jìn)行了處理。順便說(shuō)一句,這是C 和C++程序開(kāi)發(fā)環(huán)境和工具能夠被簡(jiǎn)化的一個(gè)主要原因:人與編譯器看到的是不同的東西。

不幸的是,你不能假設(shè)別的程序員總是能夠避免這種你認(rèn)為“相當(dāng)白癡”的事情。例如,最近有人報(bào)告我,他們遇到了一個(gè)包含goto 的宏。我也見(jiàn)過(guò)這種情況,而且聽(tīng)到過(guò)一些——在很脆弱的時(shí)候——看起來(lái)確實(shí)有理的意見(jiàn)。例如:

#define prefix get_ready(); int ret__
#define Return(i) ret__=i; do_something(); goto exit
#define suffix exit: cleanup(); return ret__
void f(){
  prefix;
  // ...
  Return(10);
  // ...
  Return(x++);
  //...
  suffix;
}

作為一個(gè)維護(hù)的程序員,就會(huì)產(chǎn)生這種印象;將宏“隱藏”到一個(gè)頭文件中——這并不罕見(jiàn)——使得這種“魔法”更難以被辨別。

一個(gè)常見(jiàn)的微妙問(wèn)題是,一個(gè)函數(shù)風(fēng)格的宏并不遵守函數(shù)參數(shù)傳遞的規(guī)則。例如:

#define square(x) (x*x)
void f(double d, int i){
  square(d); // 好
  square(i++); // 糟糕:這表示 (i++*i++)
  square(d+1); //糟糕:這表示(d+1*d+1); 也就是 (d+d+1)
  // ...
}

“d+1”的問(wèn)題,可以通過(guò)在“調(diào)用”時(shí)或宏定義時(shí)添加一對(duì)圓括號(hào)來(lái)解決:

  #define square(x) ((x)*(x)) /*這樣更好 */

但是, i++被執(zhí)行了兩次(可能并不是有意要這么做)的問(wèn)題仍然存在。

是的,我確實(shí)知道有些特殊的宏并不會(huì)導(dǎo)致C/C++預(yù)處理宏這樣的問(wèn)題。但是,我無(wú)心去發(fā)展C++中的宏。作為替代,我推薦使用C++語(yǔ)言中合適的工具,例如內(nèi)聯(lián)函數(shù),模板,構(gòu)造函數(shù)(用來(lái)初始化),析構(gòu)函數(shù)(用來(lái)清除),異常(用來(lái)退出上下文環(huán)境),等等。

好了,今天就先到這里,以后我們?cè)賮?lái)更深入的探討這個(gè)問(wèn)題

相關(guān)文章

  • Qt中JSON使用的詳細(xì)步驟

    Qt中JSON使用的詳細(xì)步驟

    本文主要介紹了Qt中JSON使用的詳細(xì)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • 詳析C++中的auto

    詳析C++中的auto

    這篇文章主要介紹了詳析C++中的auto,auto是具有自動(dòng)存儲(chǔ)器的局部變量,C++11中,標(biāo)準(zhǔn)委員會(huì)賦予了auto全新的含義即:auto不再是一個(gè)存儲(chǔ)類型指示符,而作為一個(gè)新的類型指示符來(lái)指示編譯器,下面來(lái)看看文章的詳細(xì)介紹吧
    2022-01-01
  • 基于C語(yǔ)言代碼實(shí)現(xiàn)點(diǎn)餐系統(tǒng)

    基于C語(yǔ)言代碼實(shí)現(xiàn)點(diǎn)餐系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了基于C語(yǔ)言代碼實(shí)現(xiàn)點(diǎn)餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • C++?using?編譯指令與名稱沖突問(wèn)題

    C++?using?編譯指令與名稱沖突問(wèn)題

    using?編譯指令由名稱空間名和它前面的關(guān)鍵字?using?namespace?組成,它使名稱空間中的所有名稱都可用,而不需要使用作用域解析運(yùn)算符,這篇文章主要介紹了C++?using?編譯指令與名稱沖突,需要的朋友可以參考下
    2022-11-11
  • C語(yǔ)言實(shí)現(xiàn)撲克牌計(jì)算24點(diǎn)

    C語(yǔ)言實(shí)現(xiàn)撲克牌計(jì)算24點(diǎn)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言如何實(shí)現(xiàn)撲克牌計(jì)算24點(diǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C++?數(shù)據(jù)結(jié)構(gòu)超詳細(xì)講解單鏈表

    C++?數(shù)據(jù)結(jié)構(gòu)超詳細(xì)講解單鏈表

    這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之單鏈表,鏈表是由一個(gè)個(gè)結(jié)點(diǎn)鏈結(jié)成的。結(jié)點(diǎn)包括數(shù)據(jù)域和指針域兩部分,數(shù)據(jù)域用來(lái)存儲(chǔ)數(shù)據(jù)元素的信息,指針域用來(lái)存儲(chǔ)下一個(gè)結(jié)點(diǎn)的地址,更詳細(xì)內(nèi)容請(qǐng)需要的小伙伴參考下面文章內(nèi)容
    2022-03-03
  • C++ sdl實(shí)現(xiàn)渲染旋轉(zhuǎn)視頻的方法分享

    C++ sdl實(shí)現(xiàn)渲染旋轉(zhuǎn)視頻的方法分享

    一般情況下播放視頻時(shí)不需要旋轉(zhuǎn),但是如果是移動(dòng)端錄制的視頻有時(shí)會(huì)出現(xiàn)rotate參數(shù),且視頻寬高也是互換的。所以本文為大家準(zhǔn)備了利用sdl實(shí)現(xiàn)渲染旋轉(zhuǎn)視頻的方法,需要的可以參考一下
    2022-12-12
  • windows下在vim中搭建c語(yǔ)言開(kāi)發(fā)環(huán)境的詳細(xì)過(guò)程

    windows下在vim中搭建c語(yǔ)言開(kāi)發(fā)環(huán)境的詳細(xì)過(guò)程

    這篇文章主要介紹了windows下在vim中搭建c語(yǔ)言開(kāi)發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • C++高性能服務(wù)器框架之線程模塊

    C++高性能服務(wù)器框架之線程模塊

    該模塊基于pthread實(shí)現(xiàn),sylar說(shuō),由于c++11中的thread也是由pthread封裝實(shí)現(xiàn)的,并且沒(méi)有提供讀寫(xiě)互斥量,讀寫(xiě)鎖,自旋鎖等,所以自己封裝了pthread,本文主要詳細(xì)介紹了C++高性能服務(wù)器框架中的線程模塊,需要的朋友可以參考下
    2023-06-06
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生選課管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生選課管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生選課管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02

最新評(píng)論