日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入浅出之预处理

發布時間:2024/9/27 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入浅出之预处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

預處理的輸出是“翻譯單元”,他是存放在內存中的臨時文件,編譯器接受預處理輸出,并將源代碼轉換成包含機器語言指令的目標文件。

1. 宏替換


1) 字符串替換

格式: #define 宏名 宏體

其中宏名與宏體均為字符串。預處理時,將把程序中該宏定義之后的所有的宏名用宏體替換。

如:

#define PI 3.14

宏替換的好處:

(1) 提高程序的可讀性

(2)易修改性好

2) 帶參數宏定義格式

#define 標識符(參數表) 宏體

例如:

#define ? PI ? 3.14
#define ? RAD ?2.0
#define ? AREA return(PI*RAD*RAD)
帶參數宏替換與函數區別:

(1) 時空效率不同,帶參數宏替換效率比函數高

(2) 宏雖然可以帶有參數,但宏替換過程中不像函數那樣可以進行參數值的計算、傳遞及結果返回等操作;宏替換只是簡單的字符替換,不進行計算。因此一些過程中不能用宏替換,比如遞歸調用;

?2.?書寫#define命令應注意事項


1) 宏名與宏體之間應以空格相隔,所以宏名中不能含有空格

2) 宏名不能用引號括起來

比如#define “YES” 1 ?不進行宏替換

3) 較長的宏定義在一行中如果寫不下時,可以在本行末尾使用反斜杠表示要續行

#define PRX printf(“ssss \ddddd”)

4) ?對帶參數宏定義,宏體及其各個形參應該用圓括號括起來

#include <QCoreApplication> //#include "test.h" #define f(x) x*x #define g(x) (x)*(x) #define h(x) ((x)*(x)) int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);qDebug("1:%d",f(2+2));qDebug("2:%d",g(2+2));qDebug("3:%d",h(2+2));return a.exec(); } 輸出: 1:8 【2+2*2+2=8】 2:16【(2+2)*(2+2)=16】 3:16【((2*2)*(2*2))=16】

5) 宏定義不是C語言,不必再行末加分號

6)宏被定義后,一般不能再重新定義,而只能使用#undef命令終止該宏定義作用域(#undef 宏名)?

3. 文件包含


?格式1: #include “文件標識符”

按這種格式定義時,預處理程序首先在原來的源文件目錄中檢索該指定的文件;如果沒有找到,則按系統指定的標準方式檢索其他文件目錄,直至找到為止;

格式2:#include <文件標識符>

按這種格式定義時,預處理程序只在系統庫中尋找指定文件。

4. 條件編譯


條件編譯可使同一源程序在不同的編譯條件得到不同的目標代碼。

格式1:

#ifdef 標識符程序段1#else程序段2#endif


格式2:

#ifndef 標識符程序段1#else程序段2#endif


在工程的地方條件指示符#ifndef的最主要目的是防止頭文件的重復包含和編譯。

#ifndef _頭文件名_H #define _頭文件名_H.... #endif


格式3:

#if 表達式1程序段1#elif 表達式2程序段2#endif

5. #define宏定義的缺點

?1)?無法對宏定義中的變量進行類型檢查

define定義的變量,是Compile-Time時期的變量,系統在編譯時候,就將其全部替換,而不會對其變量進行類型等屬性檢查,相對不是很安全,可能存在潛在的問題,而沒有發現。正因為其僅僅是編譯時期替換,所以其定義的變量,是不會在運行時候分配內存的,不占用內存空間。

2)?未加括號帶來的邊界效應

由于宏定義的時候,其各個分量未加括號,而在使用宏定義的時候,傳遞的參數是變量的表達式,然后經過系統展開后,由于優先級的原因,導致其結果不是你所希望的。

#define MUL(A,B) A*B而在使用的時候,這樣的調用:int a=1,b=2,c=3,d=0;d=MUL(a+b,c)經過編譯時候展開,就變成了d=a+b*c而不是我們所希望的d=(a+b)*c[解決辦法]其解決辦法也很簡單,就是給每個分量,都加上括號,就可以避免此類問題即,在宏定義的時候,如此定義:#define MUL(A,B) ((A)*(B))

6. #define替代方案?

1)?用const代替define來定義常量

const TYPE ValueName = value;


2)用inline代替define來定義函數
define定義函數的最大缺點就是它只是簡單替換,所以函數的參數可能會改變函數的行為。
比如上面定義的max,如果有這么一段代碼:

int a = 5, b = 0;
max(++a, b);? ? ? ? // a is incremented twice
max(++a, b+10);? ? ? // a is incremented once


可以看到對兩次調用,++a執行的次數是不一樣的。而如果用inline,寫成如下形式:

inline int max(int a, int b) { return a > b ? a : b; }

7.C++ 中的預定義宏?

  • 輸出當前行的行號

預定義宏為:__LINE__,注意,是兩個下劃線。
使用方法為:cout << “Current Line Number __LINE__ : ” << __LINE__ << endl;

  • 輸出當前文件名

預定義宏為:__FILE__
使用方法為:cout << “Current File Name __FILE__ : ” << __FILE__ << endl;

  • 輸出當前文件編譯日期

解釋:形式為 month/day/year 的字符串,它表示把源文件轉換為目標代碼的日期。
預定義宏為:__DATE__
使用方法為:cout << “Current Date __DATE__ : ” << __DATE__ << endl;

  • 輸出當前文件編譯時間

解釋:形式為 hour:minute:second 的字符串,它表示程序被編譯的時間。
預定義宏為:__TIME__
使用方法為:cout << “Current Time__TIME__ : ” << __TIME__ << endl;
?

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的深入浅出之预处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。