C语言预处理指令详解

本文详细介绍了C语言预处理器的重要概念,包括#define定义宏、宏参数、宏展开的过程及其潜在问题。讨论了宏与函数在代码长度、执行速度、操作符优先级、副作用、参数类型和调试等方面的区别。同时,讲解了#undef指令、条件编译和文件包含的用法,特别是#pragma once避免头文件重复引入的技巧。
摘要由CSDN通过智能技术生成

1.预处理符号

  • FILE进行编译的源文件
    LINE文件当前的行号
    DATE文件被编译的日期
    TIME文件被编译的时间
    STDC如果编译器遵循ANSI C,其值为1,否则未定义

#define

  • #define 定义标识符

  • #define MAX 1000

  • 在define定义标识符的时候,不要在最后加上 ;

  • #define 定义宏

  • #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏

  • 由替换产生的表达式并没有按照预想的次序进行求值,在宏定义上加上多个括号,这个问题便轻松的解决了

    • 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换

    • 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换

    • 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。

  • 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索

  • 使用 # ,把一个宏参数变成对应的字符串

  • ##可以把位于它两边的符号合成一个符号,它允许宏定义从分离的文本片段创建标识符

宏和函数的对比

属 性#define定义宏函数
代 码 长 度每次使用时,宏代码都会被插入到程序中。除了非常 小的宏之外,程序的长度会大幅度增长函数代码只出现于一个地方;每 次使用这个函数时,都调用那个 地方的同一份代码
执 行 速 度更快存在函数的调用和返回的额外开 销,所以相对慢一些
操 作 符 优 先 级宏参数的求值是在所有周围表达式的上下文环境里, 除非加上括号,否则邻近操作符的优先级可能会产生 不可预料的后果,所以建议宏在书写的时候多些括 号。函数参数只在函数调用的时候求 值一次,它的结果值传递给函 数。表达式的求值结果更容易预 测。
带 有 副 作 用 的 参 数参数可能被替换到宏体中的多个位置,所以带有副作 用的参数求值可能会产生不可预料的结果。函数参数只在传参的时候求值一 次,结果更容易控制。
参 数 类 型宏的参数与类型无关,只要对参数的操作是合法的, 它就可以使用于任何参数类型。函数的参数是与类型有关的,如 果参数的类型不同,就需要不同 的函数,即使他们执行的任务是 不同的。
调 试宏是不方便调试的函数是可以逐语句调试的
递 归宏是不能递归的函数是可以递归的
  • 一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者 那我们平时的一个习惯是:把宏名全部大写,函数名不要全部大写

  • #undef 这条指令用于移除一个宏定义

  • 条件编译

  • 在编译一个程序的时候我们如果要将一条语句(一组语句)编译或者放弃是很方便的。因为我们有条件编译指令

  • 文件包含 我们已经知道, #include 指令可以使另外一个文件被编译。就像它实际出现于 #include 指令的地方一样

  • 预处理器先删除这条指令,并用包含文件的内容替换 这样一个源文件被包含10次,那就实际被编译10次

  • #pragma once 就可以避免头文件的重复引入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值