程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言中宏定義使用方法詳解

C語言中宏定義使用方法詳解

編輯:關於C語言

C語言中宏定義使用方法詳解


C語言中的宏替換詳解
首先看一個問題:
#include

#define PRINT_CLINE() printf("%d", ______)

int main(void)
{
PRINT_CLINE();
PRINT_CLINE();

return 0;
}
在橫線處填上適當的代碼,使得上面這段代碼的輸出為34。
我想一般人看到這個問題的時候頭腦裡都沒有明確的思路來解答這個它。我看到這個問題的時候想出了各種辦法來解答它,最終還是沒有通過編譯器的檢查,比如我想過的其中一個辦法是:
(int static i=2, i++)
想著在這個位置定義一個static變量,並且賦上初值為2,最後在加上一個i++,根據逗號運算符的運算規則,整個表達式的值應該是最後一項的值,想法確實很完美,但是這樣是通不過編譯器的!在這個位置使用一條定義變量的語句是不合法的!想了很久實在想不出來辦法了。於是重新整理了宏定義的使用方法,終於找到了答案。下面一步步來說宏定義的使用方法:

1.最簡單的替換
#defind Pi 3.14159
上面的這條語句就是比較常用的簡單替換了,在預處理階段,程序代碼中出現Pi的地方都被替換為後面的3.14159。

2.帶參數的宏替換
#define MAX(a, b) (a)>(b)?(a):(b)
這個就是帶參數的宏替換了,在代碼中使用MAX宏的時候,括號內部的參數會跟隨到宏替換中。當然這個替換需要注意的地方就是記得為每個參數加上(),不然可能會產生邊際效應。

3.字符替換符:#@
先看下面的這段代碼:
#include
#define PT_CHAR(x) printf("%c", #@x);
int main(void)
{
PT_CHAR(d);
return 0;
}
程序的輸出為d。或許你會問,那直接將宏定義中的#@x用x替換掉不就可以了麼,粗略的一看這樣的說法確實是可以的,但是宏替換的時候PT_CHAR(d)編譯器會認為d是一個傳遞的參數,既然d並非一個常量,那麼編譯器就只好認為它是一個變量了,但是這樣的話問題就出來了,d並沒有定義過!

4.字符串宏替換符:#
這個跟上面的有點類似了,比如下面的兩行代碼片段:
#define PT_STRING(x) printf("%s", #x)
PT_STRING(Hello!);
如果想要達到輸出為Hello!的目的,就要使用#x,如果不使用的話根據前面的分析,編譯器會把Hello!整體理解為一個變量,但是即便這樣理解的話,這個!也是不能作為變量的一部分的啊,所以編譯器會報出比較多的錯誤。

5.連接宏替換符:##
#define p(n) printf("symbol"#n"=%d", symbol##n)
int symbol9 = 9;
p(9);
上面的輸出為symbol9=9,symbol##n將symbol和n(也就是傳遞過來的9)連接起來,構成了變量symbol9。

6.ANSI標准中的幾個標准預定義宏
__LINE__:在源代碼中插入當前源代碼行號;
__FILE__:在源文件中插入當前源文件名;
__DATE__:在源文件中插入當前的編譯日期
__TIME__:在源文件中插入當前編譯時間;
__STDC__:當要求程序嚴格遵循ANSI C標准時該標識被賦值為1;
__cplusplus:當編寫C++程序時該標識符被定義。

看到這裡,上面的問題答案也就出來了,標准預定義宏中的__LINE__代表了源代碼在改代碼中的行號,使用這個宏就可以很方便的實現上面的功能了。
答案:#define PRINT_CLINE() printf("%d", __LINE__-4)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved