最近,做OS大作業(yè),編譯大作業(yè),和進(jìn)行實(shí)驗(yàn)室工作,強(qiáng)烈認(rèn)識到了自己對C語言的了解不多……
于是今天老圖借了本書,學(xué)習(xí)一下……
來看一下我最頭疼的define……
define的作用:
一是直接定義一個(gè)東西……類似標(biāo)記
譬如:
再提一下include的事情…… #include<XXXX>,實(shí)際上是直接把XXXX整個(gè)文件COPY了進(jìn)來……
如果出現(xiàn)這樣的情況:
如果沒有ifndef這套的話,相當(dāng)于將set中的代碼重復(fù)貼了兩次,就粗大事了……
代碼第一段ifndef test 代表:如果沒有define test,則執(zhí)行下面的那段,先 define test,然后balabala,最后endif,下次再看到這段代碼的時(shí)候,ifndef test ,此時(shí)會發(fā)現(xiàn)test已經(jīng)define過了,直接endif,中間balabala的代碼不會重復(fù)兩次……
二是直接定義一些……怎么說呢,類似替換規(guī)則的東西……
譬如:直接定義常量:
1 #define MAXN 10000
這個(gè)實(shí)際上就是直接在程序編譯之前,將里面的MAXN都替換成10000
預(yù)先定義一些常量,好處大家都懂:避免程序內(nèi)部太多的“magic number”,增強(qiáng)可讀性,也便于修改……這里相當(dāng)于直接替換,貌似C的數(shù)組,定義的時(shí)候不能用int做下標(biāo),const int也不行,只能通過這個(gè)方法,用立即數(shù)……
譬如:給一些東西改個(gè)名字:
這里有一些玄機(jī):
1:#似乎是因?yàn)闆]有轉(zhuǎn)義?所以不能胡用……
譬如:#define USEMATH #include <math.h> 是不能達(dá)到預(yù)期效果的……
2:如果這一行太長,可以用\表示和下一行連起來…… 貌似這個(gè)'\'也沒轉(zhuǎn)義, #define BACKSLASH \ 也是不行的……
譬如:可以定義一些簡單的函數(shù):
#define max(a,b) ((a) > (b) ? (a) : (b))
某種意義上這比template NB...
這樣,int c = max(a,b); 就自動(dòng)替換成 int c =((a) > (b) ? (a) : (b)); 了
此處有一個(gè)技巧:有的時(shí)候,咱們需要用大括號來實(shí)現(xiàn)這個(gè)"函數(shù)",但是,由define直接替換知道,這個(gè)替換出來,相當(dāng)于{/*balabala*/};這樣,語法是錯(cuò)的……
于是怎么辦呢……咱們可以用 do {/*balabala*/} while(0) 這樣的形式,繞開這個(gè)問題…… 在上次OS大作業(yè)上咱們都見到了……
此處還有兩個(gè)玄機(jī):一是千萬記得要加括號……為什么呢……
譬如:
#define mul(a,b) a * b
看著挺好,mul(1,2 + 3)就出事了…… 直接替換出來,是 1 * 2 + 3,就錯(cuò)了……
正確方法是:#define mul(a,b) ((a) * (b)),萬無一失……
另一個(gè)玄機(jī)是避免++,--之類的,譬如
最后有兩個(gè)用法,一個(gè)是#,#會將你作為“函數(shù)”的“參數(shù)”傳入的東西轉(zhuǎn)化為字符串;一個(gè)是...,作用一看便知:
于是今天老圖借了本書,學(xué)習(xí)一下……
來看一下我最頭疼的define……
define的作用:
一是直接定義一個(gè)東西……類似標(biāo)記
譬如:
1 #ifndef test
2 #define test
3 /*
4 balabalabala
.
5 */
6 #endif
劉JX老師在大一C++課上教育我們,寫頭文件一定要加上這么個(gè)東西……為什么呢……2 #define test
3 /*
4 balabalabala

5 */
6 #endif
再提一下include的事情…… #include<XXXX>,實(shí)際上是直接把XXXX整個(gè)文件COPY了進(jìn)來……
如果出現(xiàn)這樣的情況:
1 #include <set>
2 #include <map>
我們知道,Cpp的 map 實(shí)際上是用 set 做的,map的頭文件里肯定有一個(gè) #include <set>,那么,相當(dāng)于set這個(gè)文件在這段程序里面出現(xiàn)了兩次……2 #include <map>
如果沒有ifndef這套的話,相當(dāng)于將set中的代碼重復(fù)貼了兩次,就粗大事了……
代碼第一段ifndef test 代表:如果沒有define test,則執(zhí)行下面的那段,先 define test,然后balabala,最后endif,下次再看到這段代碼的時(shí)候,ifndef test ,此時(shí)會發(fā)現(xiàn)test已經(jīng)define過了,直接endif,中間balabala的代碼不會重復(fù)兩次……
二是直接定義一些……怎么說呢,類似替換規(guī)則的東西……
譬如:直接定義常量:
1 #define MAXN 10000
這個(gè)實(shí)際上就是直接在程序編譯之前,將里面的MAXN都替換成10000
預(yù)先定義一些常量,好處大家都懂:避免程序內(nèi)部太多的“magic number”,增強(qiáng)可讀性,也便于修改……這里相當(dāng)于直接替換,貌似C的數(shù)組,定義的時(shí)候不能用int做下標(biāo),const int也不行,只能通過這個(gè)方法,用立即數(shù)……
譬如:給一些東西改個(gè)名字:
1 #include <stdio.h>
2 #define Q scanf
3
4 int main() {
5 int a;
6 Q("%d",&a);
7 printf("%d\n",a);
8 return 0;
9 }
2 #define Q scanf
3
4 int main() {
5 int a;
6 Q("%d",&a);
7 printf("%d\n",a);
8 return 0;
9 }
這里有一些玄機(jī):
1:#似乎是因?yàn)闆]有轉(zhuǎn)義?所以不能胡用……
譬如:#define USEMATH #include <math.h> 是不能達(dá)到預(yù)期效果的……
2:如果這一行太長,可以用\表示和下一行連起來…… 貌似這個(gè)'\'也沒轉(zhuǎn)義, #define BACKSLASH \ 也是不行的……
譬如:可以定義一些簡單的函數(shù):
#define max(a,b) ((a) > (b) ? (a) : (b))
某種意義上這比template NB...
這樣,int c = max(a,b); 就自動(dòng)替換成 int c =((a) > (b) ? (a) : (b)); 了
此處有一個(gè)技巧:有的時(shí)候,咱們需要用大括號來實(shí)現(xiàn)這個(gè)"函數(shù)",但是,由define直接替換知道,這個(gè)替換出來,相當(dāng)于{/*balabala*/};這樣,語法是錯(cuò)的……
于是怎么辦呢……咱們可以用 do {/*balabala*/} while(0) 這樣的形式,繞開這個(gè)問題…… 在上次OS大作業(yè)上咱們都見到了……
此處還有兩個(gè)玄機(jī):一是千萬記得要加括號……為什么呢……
譬如:
#define mul(a,b) a * b
看著挺好,mul(1,2 + 3)就出事了…… 直接替換出來,是 1 * 2 + 3,就錯(cuò)了……
正確方法是:#define mul(a,b) ((a) * (b)),萬無一失……
另一個(gè)玄機(jī)是避免++,--之類的,譬如
#define sqr(a) ((a) * (a))
sqr(a++),如果sqr是真的函數(shù)的話,計(jì)算出沒有問題……但是define會忠實(shí)的給你替換成((a++) * (a++))……怎么加的不重要,結(jié)果就不是你想的了……最后有兩個(gè)用法,一個(gè)是#,#會將你作為“函數(shù)”的“參數(shù)”傳入的東西轉(zhuǎn)化為字符串;一個(gè)是...,作用一看便知:
1 #include <stdio.h>
2 #define max(a,b) ((a) > (b) ? (a) : (b))
3 #define PRINT(
) printf(__VA_ARGS__)
4 #define debug(x) do { \
5 PRINT(#x); \
6 PRINT(" = %d\n",(x)); \
7 } while (0)
8
9 int main() {
10 int a,b;
11 scanf("%d%d",&a,&b);
12 debug(a);
13 debug(b);
14 debug(a + b);
15 debug(max(a,b));
16 return 0;
17 }
2 #define max(a,b) ((a) > (b) ? (a) : (b))
3 #define PRINT(

4 #define debug(x) do { \
5 PRINT(#x); \
6 PRINT(" = %d\n",(x)); \
7 } while (0)
8
9 int main() {
10 int a,b;
11 scanf("%d%d",&a,&b);
12 debug(a);
13 debug(b);
14 debug(a + b);
15 debug(max(a,b));
16 return 0;
17 }