zoukankan      html  css  js  c++  java
  • define 学习体会 康某

    最近,做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 }
  • 相关阅读:
    Oct 21st-
    ContextLoaderListener 解析
    HTTPS 证书制作及使用
    Spring MVC 源码分析
    思考
    《深入理解java虚拟机》 第七章虚拟机类加载机制
    《深入理解java虚拟机》第六章 类文件结构
    《深入理解java虚拟机》第三章 垃圾收集器与内存分配策略
    《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常
    SSM-1第一章 认识SSM框架和Redis
  • 原文地址:https://www.cnblogs.com/sweetsc/p/2578698.html
Copyright © 2011-2022 走看看