C预处理器和宏

一、预处理器:

1、一般作用有如下几点:

     ①、可以根据您的请求包含其他文件   例如:#include ...     ;   #pragma(lib, "../Debug/.....");

     ②、可以选择让编译器处理哪些代码   例如:#

     ③、可以定义宏   例如:明显常量    #define .....(如果一个物理不行,可以通过“ ”,扩展到两个物理行)

     ④、预处理器一般是接受一些文本并将其转换为其他文本,不进行计算,知识按照指令进行文字替换操作

二、C 与 宏

使用宏的目的很大程度上是为了提高代码的可移植性,最基础一点,定义宏是不带分号的。

* 明显常量:#define

格式:    #define    宏    替换列表          例如: #define TWO 2          

             对比typedef格式     typedef   C类型    自定义标识符            例如:typedef unsigned char BYTE

1、宏就是缩略语,代表值的宏被称为类对象宏

2、代表函数的宏,称为类函数宏

3、宏的名字中不允许有空格,必须遵循C变量的命名规则(只能使用字母、数字、下划线)

4、一般宏定义中可以包含其他宏,即嵌套功能

5、不要在宏中使用增量和减量运算符

6、#define PSQR(X) printf(“The square of X is %d. ”)输出语句中,如果希望printf()中的X代表的是宏函数中的X,就在前面加上#。

变成#define PSQR(X) printf(“The square of” #x “is %d. ”, ((X) * (X)))

7、##可以在宏中连接两个字符:#define XNAME(n)x ## n

#define HAL ' Z '  定义字符串常量Z,以空字符串结束                  #define HAL " Z " 定义字符串Z

*用宏,还是函数

程序员一般将宏用于简单函数,如:结合三元表达式   #define MAX(X, Y)((X) > (Y) ? (X): (Y))

*使用宏要注意的几点:

①、宏的名字中不能有空格,但是在替代字符串中可以使用空格

②、用圆括号括住每个参数,并包括宏的整体定义

③、用大写字母表示宏函数名

④、在嵌套函数中使用宏更有助于加速程序运行。

*文件包含 #include

格式:一般有三种,eg: #include <stdio.h> (搜索系统目录)  

#include " mystuff.h"(搜索当前工作目录)

#include < GL/glut.h >(搜索GL文件夹下的glut.h) #include < /usr/biff/p.h >搜索/usr/biff目录下的p.h

头文件的主要作用通常是提供编译器用于产生可执行代码的信息,例如:函数声明,宏定义,类型定义,结构声明、类声明等等。

 *其他宏指令

空宏的作用(空宏在预编译时被替换成空字符串)

①、空的宏的作用是预留下以后平台移植时的其它选项的定义,是为了移植的方便。

②、增强代码的可读性

③、跟条件编译一起用#define MAVIS ;    #ifdef MAVIS

 #undef指令

作用:取消定义一个给定的#define, 即使开始没有#define,取消定义也是合法的

已定义宏可以为类对象宏(包括空宏)或类函数宏:

#define LIMIT 1000

#define GOOD

作用域:#define的作用域从文件中的的定义点开始,知道用#undef指令取消宏为止或者直到文件尾为止(由二者中最先满足的那个结束宏的作用域)。

条件编译

①、#ifdef、#else 和 #endif指令

②、#ifndef #else 和 #endif指令

 作用:-- 通常用于头文件的包含,使用#ifndef可以防止对该宏的重复定义,因此第一个头文件中的定义变成了有效定义,而其他头文件中的定义则被忽略。

    -- #ifndef指令通常用于防止多次包含同一文件例如:

        #ifndef  THINGS_H_

                   #define THINGS_H_

       #endif

假设多次包含了该文件,当预处理器第一次遇到该包含文件时,THINGS_H_是未定义的,因此程序定义THINGS_H_,当预处理器下一次遇到该文件时,THINGS_H_已经定义,因此预处理器跳过该文件的其余部分。

头文件写成THINGS_H_的原因是避免头文件的标识符也就是头文件名在其他地方没有定义过,因为C标准保留使用下划线作为前缀,因此最好是只把头文件的“.”和后缀改成下划线“_”,这样保证不发生冲突。

③、#if 和 #elif 指令

举例说明:

#if 指令

#if SYS == 1

#include "ibm.h"

#endif

#elif指令

#if SYS == 1 

     #include "ibmpc.h"

#elif SYS == 2

      #include "vax.h"

新的实现用  #if defined( VAX ) 来代替 #ifdef VAX

如果用在VAX的机器上,应该在前面加上#define VAX

总结:都要跟宏定义结合起来使用

④、#pragma

在现代的编译器中,可以用命令行参数或ICE菜单修改编译器的某些配置。也可以用#pragma将编译器指令置于源代码中。#pragma表示编译指示

例如链接lib文件可以用以下编译指示

#pragma comment(lib,“ .../Debug/Test.lib ”) //表示链接Test.lib文件

#pragma comment(linker,"/ENTRY:main_function")//表示指定链接器选项/ENTRY:main_function

#pragma once //保证所在文件只会被包含一次,它是基于磁盘文件的,而#ifndef则是基于宏的

#pragma warning(disable:4705)  //表示屏蔽警告4705

#pragma的更多用法参考qinfengxiaoyue博客园的文章

http://www.cnblogs.com/qinfengxiaoyue/archive/2012/06/05/2535524.html

原文地址:https://www.cnblogs.com/develop-me/p/5675855.html