zoukankan      html  css  js  c++  java
  • 预处理指令1-宏定义

    预处理指令简介:
      1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译
      2.为了区分预处理指令和一般的C语句,所有预处理指令都以符号"#"开头,并且结尾不用分号
      3.预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾。习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件
      4.C语言提供的预处理指令主要有:宏定义、文件包含、条件编译

    宏定义可以分为2种: 不带参数的宏定义 和 带参数的宏定义。
      一、不带参数的宏定义:
        #define 宏名 字符串 (比如#define ABC 10)
        1 #include <stdio.h>
        2
        3 // 源程序中所有的宏名PI在编译预处理的时候都会被3.14所代替
        4 #define PI 3.14
        5
        6 // 根据圆的半径计radius算周长
        7 float girth(float radius) {
        8 return 2 * PI *radius;
        9 }
        10
        11 int main ()
        12 {
        13 float g = girth(2);
        14
        15 printf("周长为:%f", g);
        16 return 0;
        17 }

        使用习惯与注意:
        1> 宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误
        2> 对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作。比如:
            1 #define R 10
            2 int main ()
            3 {
            4 char *s = "Radio"; //"Radio"里面的'R'不会被替换成10
            5 return 0;
            6 }
        3> 在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查
          1 #define I 100
          2 int main ()
          3 {
          4 int i[3] = I;
          5 return 0;
          6 }
          在做编译预处理的时候,不管语法对不对,第4行的I都会被替换为100。不过在编译的时候就会报第4行的错。
        4> 宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令
          1 #define PI 3.14
          2 /*
          3 .
          4 .
          5 .
          6 .
          7 */
          8 #undef PI
        5> 定义一个宏时可以引用已经定义的宏名
          #define R 3.0
          #define PI 3.14
          #define L 2*PI*R
          #define S PI*R*R

      二、带参数的宏定义:
        #define 宏名(参数列表) 字符串
        在编译预处理时,将源程序中所有宏名替换成字符串,并且将 字符串中的参数 用 宏名右边参数列表 中的参数替换
          1 #include <stdio.h>
          2
          3 #define average(a, b) (a+b)/2
          4
          5 int main ()
          6 {
          7 int a = average(10, 4);
          8
          9 printf("平均值:%d", a); //平均值:7
          10 return 0;
          11 }

      使用注意:
          1> 宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串。
          2> 带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,一般用一个小括号括住字符串的参数。
          3> 计算结果最好也用括号括起来

    与函数的区别:
        从整个使用过程可以发现,带参数的宏定义,在源程序中出现的形式与函数很像。但是两者是有本质区别的:
          1> 宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题
          2> 函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。所以带参数的宏比函数具有更高的执行效率

  • 相关阅读:
    js对象数组(JSON) 根据某个共同字段 分组
    一个 函数 用来转化esSearch 的range 条件
    关于 vuex 报错 Do not mutate vuex store state outside mutation handlers.
    android listview 重用view导致的选择混乱问题
    android SDK和ADT的更新
    Android中adb push和adb install的使用区别
    pycharm中添加扩展工具pylint
    su Authentication failure解决
    Putty以及adb网络调试
    有关android源码编译的几个问题
  • 原文地址:https://www.cnblogs.com/tzktzk1/p/3329453.html
Copyright © 2011-2022 走看看