C++:宏替换的误区

看下面的代码,输出的结果是什么呢?

#include <iostream>
using namespace std;
#define NUM 0

void fun()
{
    #undef NUM
    #define NUM 100
}
int main()
{
    fun();
    cout<<"NUM="<<NUM<<endl;//NUM=100;
    return 0;
}

没错,答案是100,再看下面这段代码:

#include <iostream>
using namespace std;
#define NUM 0
void fun();

int main()
{
    fun();
    cout<<"NUM="<<NUM<<endl;//NUM=0;
    return 0;
}

void fun()
{
    #undef NUM
    #define NUM 100
}

输出的结果是0,为什么呢?此刻我得出的初步结论是,宏替换并不是扫描全文件然后全部替换,为了解决我的疑问,我把宏处理之后两个函数代码图截取下来了。

很明显替换结果并不一样。

#include <iostream>
using namespace std;
void fun();
int main()
{
    fun();
    OUT;
    //main.cpp:7: error: ‘OUT’ was not declared in this scope
        //明显出错了,因为到main函数的时候看不到OUT。
    return 0;
}
void fun()
{
#define OUT cout<<"hello word"<<endl
}
//由此可以得出,宏替换并不是在预处理的时候替换所有的宏,
//只会替换在main函数之前可见的,如果定义在main函数后面的
//宏定义是不会展开的,所以在main里面是看不到宏改变或者宏定义的。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 21:50:55

C++:宏替换的误区的相关文章

ISO/IEC 9899:2011 条款6.10.3——宏替换

6.10.3 宏替换 约束 1.两个替换列表是相同的,当且仅当两个替换列表中的预处理符记都具有相同的数.次序.拼写,以及空白分隔符,这里所有的空白分隔符都认为是相同的. 2.当前被定义为一个类似对象的宏的标识符不应该被另一个#define预处理指示符重新定义,除非第二个定义是一个类似对象的宏定义,并且两个替换列表完全相同.类似的,当前被定义为类似函数的宏的标识符不应该用另一个#define预处理指示符重新定义,除非第二个定义是一个类似函数的宏定义,且具有相同个数的形参和拼写,以及两个替换列表完全

#和##在宏替换中的作用

摘自:http://blog.csdn.net/kingkai620/article/details/5905606 文/kingkaihttp://blog.csdn.net/haoel/archive/2009/05/18/4197010.aspx,其中的PUZZLE 4给出了一个关于宏的谜题.值得研究. [c-sharp] view plaincopy#include <stdio.h> #define f(a,b) a##b #define g(a) #a #define h(a) g

#define(宏替换)以及如何打开预编译之后的“.i”文件看宏的本质

<span style="font-size:24px;">#include<stdio.h> #include<iostream.h> #define PI 3.14 /* <span style="color:#ff0000;">PI是符号常量,不开辟空间,只是个临时符号 宏的本质是:替换</span> */ int main() { double result; int r = 3; result =

C宏替换优先级

宏替换只是简单的替换,它不会影响运算符优先级的,例如: #define DOUBLE(x) x+x int i = DOUBLE(5)*5; printf("%d", i); 相当于i=5+5*5.i=30而不是50

带参数的宏替换

带参数的宏替换因各种需求叠加,替换规则很怪异: 1.首先将实参替换形参,并展开宏 2.如果1步展开后,有#或者##,那么停止替换. 3.如果1步展开后,没有#或者##,且参数也是宏,那么继续替换,知道参数没有宏为止. 4.执行完1-3后,第一轮替换结束,再次扫描宏,如果外层还有宏,继续替换. 5.简单说:先用实参代替形参,然后继续替换实参内的宏,发现#或##后停止. 原文地址:https://www.cnblogs.com/litifeng/p/8424078.html

宏常量,宏替换,const常量

(1)宏常量也称为符号常量,是指用一个标识符号来表示的常量,宏常量是由宏定义编译预处理命令来定义的,宏定义的一般形式:#define 标识符 字符串 宏定义中的标识符被称为宏名,将程序中出现的宏名替换成字符串的过程称为宏替换,宏替换时是不做任何语法检查的,因此,只有在对已经被宏展开后的源程序进行编译时才会发现语法错误 (2)const常量:使用宏常量的最大问题是,宏常量没有数据类型.那么是否可以声明具有某种数据类型的常量呢?这就是const常量 const常量被编译器放在只读存储区,不允许在程序

预编译时宏替换 见解

在预编译的过程中  主要处理#  和宏替换 例如 #include<stdio.h> #define PI 3.14 int main(){ double r=3, s; s=r*r*PI; printf("%f\n",s); return 0; } 在预编译的时候   代码变成如下 #include<stdio.h> int main(){ double r=3, s; s=r*r*3.14; printf("%f\n",s); retur

word中利用宏替换标点标点全角与半角

Alt+F11,然后插入-模块: 复制下面代码到编辑窗口: Sub 半角标点符号转换为全角标点符号() '中英互译文档中将中文段落中的英文标点符号替换为中文标点符号 Dim i As Paragraph, ChineseInterpunction() As Variant, EnglishInterpunction() As Variant Dim MyRange As Range, N As Byte '定义一个中文标点的数组对象 ChineseInterpunction = Array(".

final变量中的宏替换

源代码1: public class Java15 { public static void main(String[] args) { String s1="疯狂java"; String s2="疯狂"+"java"; System.out.println(s1==s2); String str1="疯狂"; String str2="java"; String s3=str1+str2; System