[NKU]sweet @ Google && TopCoder && CodeForces

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            33 Posts :: 1 Stories :: 15 Comments :: 0 Trackbacks
          最近,做OS大作業,編譯大作業,和進行實驗室工作,強烈認識到了自己對C語言的了解不多……
          于是今天老圖借了本書,學習一下……
          來看一下我最頭疼的define……
          define的作用:
          一是直接定義一個東西……類似標記
          譬如:
          1 #ifndef test
          2 #define test
          3 /*
          4 balabalabala.
          5 */
          6 #endif
          劉JX老師在大一C++課上教育我們,寫頭文件一定要加上這么個東西……為什么呢……
          再提一下include的事情…… #include<XXXX>,實際上是直接把XXXX整個文件COPY了進來……
          如果出現這樣的情況:
          1 #include <set>
          2 #include <map>
          我們知道,Cpp的 map 實際上是用 set 做的,map的頭文件里肯定有一個 #include <set>,那么,相當于set這個文件在這段程序里面出現了兩次……
          如果沒有ifndef這套的話,相當于將set中的代碼重復貼了兩次,就粗大事了……
          代碼第一段ifndef test 代表:如果沒有define test,則執行下面的那段,先 define test,然后balabala,最后endif,下次再看到這段代碼的時候,ifndef test ,此時會發現test已經define過了,直接endif,中間balabala的代碼不會重復兩次……

          二是直接定義一些……怎么說呢,類似替換規則的東西……

          譬如:直接定義常量:
          1 #define MAXN 10000
          這個實際上就是直接在程序編譯之前,將里面的MAXN都替換成10000
          預先定義一些常量,好處大家都懂:避免程序內部太多的“magic number”,增強可讀性,也便于修改……這里相當于直接替換,貌似C的數組,定義的時候不能用int做下標,const int也不行,只能通過這個方法,用立即數……

          譬如:給一些東西改個名字:
            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 } 

          這里有一些玄機:
          1:#似乎是因為沒有轉義?所以不能胡用……
          譬如:#define USEMATH #include <math.h> 是不能達到預期效果的……
          2:如果這一行太長,可以用\表示和下一行連起來…… 貌似這個'\'也沒轉義, #define BACKSLASH \ 也是不行的……

          譬如:可以定義一些簡單的函數:
          #define max(a,b) ((a) > (b) ? (a) : (b))
          某種意義上這比template NB...
          這樣,int c = max(a,b); 就自動替換成 int c =((a) > (b) ? (a) : (b)); 了
          此處有一個技巧:有的時候,咱們需要用大括號來實現這個"函數",但是,由define直接替換知道,這個替換出來,相當于{/*balabala*/};這樣,語法是錯的……
          于是怎么辦呢……咱們可以用 do {/*balabala*/} while(0) 這樣的形式,繞開這個問題…… 在上次OS大作業上咱們都見到了……
          此處還有兩個玄機:一是千萬記得要加括號……為什么呢……
          譬如:
          #define mul(a,b) a * b
          看著挺好,mul(1,2 + 3)就出事了…… 直接替換出來,是 1 * 2 + 3,就錯了……
          正確方法是:#define mul(a,b) ((a) * (b)),萬無一失……
          另一個玄機是避免++,--之類的,譬如
          #define sqr(a) ((a) * (a))
          sqr(a++),如果sqr是真的函數的話,計算出沒有問題……但是define會忠實的給你替換成((a++) * (a++))……怎么加的不重要,結果就不是你想的了……

          最后有兩個用法,一個是#,#會將你作為“函數”的“參數”傳入的東西轉化為字符串;一個是...,作用一看便知:
           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 }
          posted on 2011-12-02 01:59 sweetsc 閱讀(332) 評論(0)  編輯  收藏 所屬分類: 學習心得
          主站蜘蛛池模板: 仙游县| 柯坪县| 盈江县| 乌海市| 姜堰市| 体育| 资兴市| 迁安市| 赤峰市| 兴化市| 龙井市| 托里县| 台东市| 天镇县| 安庆市| 二连浩特市| 三穗县| 湟中县| 会泽县| 清水河县| 京山县| 太仆寺旗| 轮台县| 浦北县| 上杭县| 乌苏市| 东港市| 平远县| 综艺| 桐乡市| 聂拉木县| 浦江县| 邻水| 庄浪县| 江都市| 石门县| 灵山县| 贵定县| 兰考县| 华容县| 山阳县|