C语言中的宏替换详解
首先看一个问题:
#include <stdio.h>

#define    PRINT_CLINE()    printf("%d", ______)

int main(void)
{    
    PRINT_CLINE();
    PRINT_CLINE();

return 0;
}
在横线处填上适当的代码,使得上面这段代码的输出为34。
我想一般人看到这个问题的时候头脑里都没有明确的思路来解答这个它。我看到这个问题的时候想出了各种办法来解答它,最终还是没有通过编译器的检查,比如我想过的其中一个办法是:
(int static i=2, i++)
想着在这个位置定义一个static变量,并且赋上初值为2,最后在加上一个i++,根据逗号运算符的运算规则,整个表达式的值应该是最后一项的值,想法确实很完美,但是这样是通不过编译器的!在这个位置使用一条定义变量的语句是不合法的!想了很久实在想不出来办法了。于是重新整理了宏定义的使用方法,终于找到了答案。下面一步步来说宏定义的使用方法:

1.最简单的替换
#defind    Pi    3.14159   
上面的这条语句就是比较常用的简单替换了,在预处理阶段,程序代码中出现Pi的地方都被替换为后面的3.14159。

2.带参数的宏替换
#define    MAX(a, b)    (a)>(b)?(a):(b)
这个就是带参数的宏替换了,在代码中使用MAX宏的时候,括号内部的参数会跟随到宏替换中。当然这个替换需要注意的地方就是记得为每个参数加上(),不然可能会产生边际效应。

3.字符替换符:#@
先看下面的这段代码:
#include <stdio.h>
#define PT_CHAR(x) printf("%c", #@x);
int main(void)
{
    PT_CHAR(d);
    return 0;
}
程序的输出为d。或许你会问,那直接将宏定义中的#@x用x替换掉不就可以了么,粗略的一看这样的说法确实是可以的,但是宏替换的时候PT_CHAR(d)编译器会认为d是一个传递的参数,既然d并非一个常量,那么编译器就只好认为它是一个变量了,但是这样的话问题就出来了,d并没有定义过!

4.字符串宏替换符:#
这个跟上面的有点类似了,比如下面的两行代码片段:
#define PT_STRING(x) printf("%s", #x)
PT_STRING(Hello!);
如果想要达到输出为Hello!的目的,就要使用#x,如果不使用的话根据前面的分析,编译器会把Hello!整体理解为一个变量,但是即便这样理解的话,这个!也是不能作为变量的一部分的啊,所以编译器会报出比较多的错误。

5.连接宏替换符:##
#define   p(n)   printf("symbol"#n"=%d", symbol##n)  
int   symbol9 = 9;  
p(9);   
上面的输出为symbol9=9,symbol##n将symbol和n(也就是传递过来的9)连接起来,构成了变量symbol9。

6.ANSI标准中的几个标准预定义宏
__LINE__:在源代码中插入当前源代码行号;
__FILE__:在源文件中插入当前源文件名;
__DATE__:在源文件中插入当前的编译日期
__TIME__:在源文件中插入当前编译时间;
__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;
__cplusplus:当编写C++程序时该标识符被定义。

看到这里,上面的问题答案也就出来了,标准预定义宏中的__LINE__代表了源代码在改代码中的行号,使用这个宏就可以很方便的实现上面的功能了。
答案:#define    PRINT_CLINE()    printf("%d", __LINE__-4)

C语言中宏定义使用方法详解相关推荐

  1. 如何用C语言改变宏定义的大小,C语言中宏定义使用的小细节

    C语言中宏定义使用的小细节 #pragma#pragma 预处理指令详解 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#p ...

  2. C/C++编程笔记:浅析 C 语言中宏定义的使用,知识点全解

    宏定义是用一个标识符来表示一个字符串,在宏调用中将用该字符串代替宏名.给程序员提供了便利,使程序更加清晰,便于阅读和理解,进一步提高了程序的运行效率,对于嵌入式系统而言,为了能达到性能要求,宏是一种很 ...

  3. C语言中三个数比较大小详解——三种方法

    ​ C语言中三个数比较大小详解--三种方法 方法一:if-else法 方法二:函数法 方法三:三目运算符法 C语言中比较三个数的大小有很多方法,以下是我总结的三种方法: 首先我定义 int a = 1 ...

  4. c语言中宏定义的字符替换#define M(x,y,z) x*y+z

    C语言中宏定义的字符替换问题 例子: 在c语言中定义如下宏 #define M(x,y,z) x*y+z 给定如下程序 #include<stdio.h> #include<stdl ...

  5. c语言结构体成员变量私有化,C语言中结构体变量私有化详解

    C语言中结构体变量私有化详解 背景介绍 操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 什么是结构体? 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚 ...

  6. c语言二级指针有什么作用,C语言中二级指针的实例详解

    C语言中二级指针的实例详解 C语言中二级指针的实例详解 用图说明 示例代码: #include int main(int argc, const char * argv[]) { // int a = ...

  7. php中this的使用技巧,JavaScript中this关键字使用方法详解

    JavaScript中this关键字使用方法详解 在面向对象编程语言中,对于this关键字我们是非常熟悉的.比如C++.C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了 ...

  8. android json mysql_Android通过json向MySQL中读写数据的方法详解【读取篇】

    本文实例讲述了Android通过json向MySQL中读取数据的方法.分享给大家供大家参考,具体如下: 首先 要定义几个解析json的方法parseJsonMulti,代码如下: private vo ...

  9. c语言自定义color,forecolor c语言中的颜色设置语句详解

    backcolor与forecolor的区别 backcolor:用来设置图像的背景颜色,也用来设置文档.表格.图像等的背景颜色. forecolor:用来设置图像的前景颜色,也用来设置文档.表格.图 ...

最新文章

  1. saltui试用遇到的问题
  2. 有氧运动 无氧运动
  3. 八大编程知名编程语言或系统的发展简史
  4. jaxb list集合对象_JAXB –表示空集合和空集合
  5. 八、pink老师的学习笔记—— CSS用户界面样式(鼠标样式、轮廓线、防止拖拽文本域)
  6. 【数据库系统】事务、锁、隔离、自动恢复
  7. 常用PHP数组函数总结
  8. wxPython控件学习之StaticText静态文本框
  9. Tricks(二十)—— 从 N 个数中等概率地产生 M 个数
  10. mysql定时任务多条sql_【SQL】使用Navicat创建MySQL定时任务重复执行某个sql语句
  11. 随机出题在线考试系统php_在线考试系统怎么实现自制题库随机出题
  12. multisim 10 基本分析法的应用1
  13. 虚拟机VMware 15安装教程
  14. 项目管理能力提升四要素
  15. Android init.rc介绍及其语法
  16. 用户体验 | 银行如何优化APP用户体验
  17. AP 计算机 一次完美的逆袭
  18. 答疑解惑 | Linux GNU C 与 ANSI C 的区别
  19. 祝早道日语七周年快乐!
  20. C/C++蓝桥杯三升序列

热门文章

  1. dataframe求两列的相乘,再将输出为新的一列
  2. SpringCloud返回的是xml格式而非JSON数据
  3. 王立铭紧急发声:为什么基因编辑婴儿在今天不可原谅?
  4. java 导出excel 大数据量 报错_java导出excel
  5. Flutter关于布局
  6. 人工智能编程语言c,最适合人工智能开发的5种编程语言
  7. Dart 学习笔记一(操作符、方法与异常)
  8. 20. ROUTINES
  9. 【Vue.js】用vue组件完成官网实时markdown示例
  10. GlusterFS:统一命名空间(Unify)源码分析