zoukankan      html  css  js  c++  java
  • 第二章 预处理

    一、文件的包含方式

    1)#include"文件名"
    2)#include<文件名>
    

      查找文件的顺序不同,一个先从当前目录开始查找;一个先从系统目录开始查找。

    二、宏定义

      0.基础介绍

      宏定义又称为宏替换,是在预处理阶段用预先定义的字符串替代标示符的过程。其定义一般形式为:

    #define  标示符  字符串
    

      宏定义的标示符一般情况下都大写,这是一种约定俗成的习惯。使用宏定义需要注意以下几点:

      1)宏替换不做语法检查,使用的时候要特别小心

      2)宏替换通常在文件开头部分,写在函数的花括号外边,作用域为气候的程序,直到#undef命令终止宏定义的作用域

      3)不要在字符串中使用宏,如果宏名出现在字符串中,那么将按字符串进行处理

      1.简单宏替换

      宏定义的优点:1)减少不必要的修改,提升程序的可阅读性 2)提升代码的可移植性

      使用宏定义需要注意的问题:宏定义只是简单的替换,要清楚的理解其替换后的意义

      2.带参数的宏替换

      带参数的宏替换,其定义的一般形式为:

    #define 宏名(参数表) 字符串
    

      使用带参数的宏时需要注意以下几点:

      1)宏名和参数表的括号间不能有空格

      2)宏替换只做替换,不做计算和表达式求解

      3)函数调用在编译后程序运行时进行,并且分配内存,宏替换在编译前进行,不分配内存

      4)宏的哑实结合(哑实结合类似于函数调用过程中实参替代形参的过程)不存在类型,也没有类型转换

      两个标准的宏,但是只能在linux下运行:

    #define min(x,y) ({typeof(x)_x = x;typeof(y)_y=y;(void)(&_x==&_y);_x<_y?_x:_y;})
    #define max(x,y) ({typeof(x)_x = x;typeof(y)_y=y;(void)(&_x==&_y);_x>_y?_x:_y;})
    

      可以细细去体会其中的奥妙:a.typeof的意义是什么?b.void(&_x==&_y)的意义是什么?c.为什么要加{}?4.为什么外面需要()?

      3.宏定义实现变参

      带变参的宏的一般形式为:

    #define print(......) printf(__VA_ARGS__)
    

      在这个宏中,“......”指可变参数。可变参数的实现方式就是使用“......”所代表的内容替代__VA_ARGS__,下面代码演示:

    #include<stdio.h>
    #define print(......) printf(__VA_ARGS__)
    int main(int argc, char *argv)
    {
            print("hello world----%d
    ",1111);
            return 0;
    }
    

    三、条件编译指令的使用

      预处理程序提供了条件编译的功能,用户可以选择性地编译程序,进而产生不同的目标代码文件,这对程序的移植性和调试来说是非常有用的。下面来看条件编译命令的几种使用方式:

    1)第一种方式:
    
    #if 常量表达式
    程序段1;
    #else
    程序段2;
    #endif
    
    2)第二种方式:
    
    #ifdef 标示符
    程序段1;
    #else
    程序段2;
    #endif
    
    3)第三种方式:
    
    #ifndef 标示符
    程序段1;
    #else
    程序段2;
    #endif
    

     四、#pragma指定的使用

      预处理#pragma指令的作用不只是指定字节对齐,其作用是设置编译器的状态或指示编译器完成一些特定的动作。

      1.#pragma mesage("消息")

      该打印输出的信息是在编译期输出,不会出现在程序最终的运行结果中。通过这种方式,可以在代码中输出想要的信息,也可以看某个宏是否已经被定义过。

    #include<stdio.h>
    #define STR
    void main(int argc, _TCHAR* argv[])
    {
    	printf("学习#pragma命令中message参数的使用!
    ");
    #ifdef STR
    #pragma message("STR已经定义过了。")
    #endif
    	return;
    }
    

      2.#pragma once

      如果在头文件的开头部分加入这条指令,那么就能保证头文件只被编译一次

      3.#pragma hdrstop

      该指令表示编译头文件到此为止,后面的无需再编译了

      4.#pragma pack()

      设定字节对齐

      5.#pragma warning()

  • 相关阅读:
    Effective Java 第三版——26. 不要使用原始类型
    Effective Java 第三版——25. 将源文件限制为单个顶级类
    Effective Java 第三版——24. 优先考虑静态成员类
    Effective Java 第三版——23. 优先使用类层次而不是标签类
    Effective Java 第三版——22. 接口仅用来定义类型
    Effective Java 第三版——21. 为后代设计接口
    Effective Java 第三版——20. 接口优于抽象类
    Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
    Effective Java 第三版——18. 组合优于继承
    Effective Java 第三版——17. 最小化可变性
  • 原文地址:https://www.cnblogs.com/cauchy007/p/4547986.html
Copyright © 2011-2022 走看看