C和指针-第十四章-预处理器

本文详细介绍了C语言的预处理指令,包括#define定义宏、#undef移除宏定义、#if条件编译、#include文件包含等。阐述了宏定义的使用规则、参数处理技巧,以及不同指令的功能、用法和示例,还提及防止文件多次包含、生成错误信息等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define

DESCRIPTION: 定义一个宏

NOTE: 
    1 所有用于表达式求值的宏定义都应该对参数加上括号,避免在使用宏时,由于参数中操作符或邻近的操作符之间不可预料的相互作用
    2 宏与类型无关
    
USAGE1: #define name [stuff]
EXPLANATION: 当符号出现在这条指令后面时, 预处理就会把它替换成stuff

COMMAND: gcc -E main.c -o main.i

EXAMPLES:
    #define reg register
    #define do_forever for(;;)
    #define CASE break;case
    
    
USAGE2: #define name(parameter-list) [stuff]
ATTENTION: parameter-list是一个由都好分隔的符号列表,它们可能出现在stuff中。
           参数列表的左括号必须与name紧邻,如果两者之间有空白存在,参数列表就会被解释为stuff的一部分;


将宏参数插入到字符串常量中    
SKILL1: 邻近字符串自动链接的特性
    #define PRINT(FORMAT, VALUE) \
            printf("The value is " FORMAT "\n", VALUE)
    
    PRINT("%d", 5)预处理后的结果为: printf("The value is " "%d" "\n", 5) 等价于 printf("The value is %d \n", 5)
    
SKILL2: 使用预处理器把一个宏参数转换为一个字符串
    #define PRINT(FORMAT, VALUE) \
            printf("The value of " #VALUE \
            " is " FORMAT "\n", VALUE)
            
    PRINT("%d", x + 3) 预处理后的结果为: printf("The value of " "x + 3" " is " "%d" "\n", x + 3) 等价于 printf("The value of x + 3 is %d\n", x + 3)    

SKILL3:##将它两边的符号连接成一个符号, ##左右两边有无空格效果一样
    #define ADD_TO_SUM( sum_number, value) \
            sum ## sum_number += value
    
    ADD_TO_SUM(5, 5)预处理后的结果为: sum5 += 5
        


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#undef

DESCRIPTION: 移除一个宏定义

USAGE: #undef name

命令行定义:
    gcc -DNAME -E main.c -o main.i                    定义一个宏NAME                     等同于    #define NAME
    gcc -DAGE=25 -E main.c -o main.i                定义一个宏AGE 25                   等同于  #define AGE 25
    gcc -DNAME="\"John\"" -E main.c -o main.i        定义一个宏NAME "John"    等同于    #define NAME "John"
    
    gcc -DNAME -UNAME -E main.c -o main.i            相当于未定义宏                 等同于 #define NAME   #undef NAME

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#if    constant-expression
        statements
#endif

DESCRIPTION: 条件编译

EXPLANATION: constant-expression 常量表达式 -> 字面量或者由#define定义的符号

#if constant-expression
        statements
#elif constant-expression
        statements
#else 
        statements
#endif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#if defined(symbol)
#ifdef symbol

#if !defined(symbol)
#ifndef symbol

DESCRIPTION: 判断是否定义

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#if defined( OS_UNIX )
    #ifdef OPTION1
        unix_version_of_option1();
    #endif
    #ifdef OPTION2
        unix_version_of_option2();
    #endif
#elif defined( OS_MSDOS )
    #ifdef OPTION2
        msdos_version_of_option2();
    #endif
#endif

DESCRIPTION: 嵌套指令

#ifdef OPTION1
    lengthy code for option1;
#else 
    lengthy code for alternative;
#endif /*OPTION1*/

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include 

DESCRIPTION: 文件包含

USAGE:#include <filename> 
       #include "filename"
       #include "/usr/lib/filename"

EXPLANATION: <filename> 和 "filename" 的区别: 前者在编译器指定的位置查找函数库头文件, 
                                               后者先在当前目录下查找指定文件,如果未找到的情况下再去编译器指定的位置查找文件       
            "usr/lib/filename" 使用绝对路径指定文件
            
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#ifndef _HEADERNAME_H
#define _HEADERNAME_H 1
#endif

DESCRIPTION: 防止文件出现多次包含的情况发生

EXAMPLES:
    main.h
    
    #ifndef _MAIN_H
    #define _MAIN_H 1
    ...
    #endif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#error

DESCRIPTION: 生成错误信息

EXAMPLES:
    #if defined( OPTION_A )
        stuff needed option A
    #elif defined( OPTION_B )
        stuff needed option B
    #elif defined( OPTION_C )
        stuff needed option C
    #else 
        #error No option selected
    #endif /* 如果未定义OPTION_A OPTION_B OPTION_C 则预处理报错 No option selected */
    
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#line 

USAGE: #line number [string]

DESCRIPTION: 修改__LINE__符号的值, 加上可选部分将修改__FILE__的值

EXPLANATION: number 为下一行输入的行号 可选字符串[string] 将修改__FILE__的值

EXAMPLES:
    main.c
    1 #include <stdio.h>
    2 
    3 #line 5 "TEST"
    4 
    5 void main() {
    6         printf("%d\n", __LINE__);
    7         printf("%s\n", __FILE__);
    8 }
    
    #line 5 "TEST"
    此时第四行的行号修改为第5行,所以此时__LINE__的值为7
    此时__FILE__的值为"TEST" 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#progma

DESCRIPTION: 用于支持因编译器而异的特性, 不可移植

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值